/* eslint-disable no-unused-vars */
/* eslint-disable no-prototype-builtins */
/* eslint-disable no-undef */
(function (f) {
  if (typeof exports === "object" && typeof module !== "undefined") {
    module.exports = f();
  } else if (typeof define === "function" && define.amd) {
    define([], f);
  } else {
    var g;
    if (typeof window !== "undefined") {
      g = window;
    } else if (typeof global !== "undefined") {
      g = global;
    } else if (typeof self !== "undefined") {
      g = self;
    } else {
      g = this;
    }
    g.adapter = f();
  }
})(function () {
  var define, module, exports;
  return (function () {
    function r(e, n, t) {
      function o(i, f) {
        if (!n[i]) {
          if (!e[i]) {
            var c = "function" == typeof require && require;
            if (!f && c) return c(i, !0);
            if (u) return u(i, !0);
            var a = new Error("Cannot find module '" + i + "'");
            throw ((a.code = "MODULE_NOT_FOUND"), a);
          }
          var p = (n[i] = { exports: {} });
          e[i][0].call(
            p.exports,
            function (r) {
              var n = e[i][1][r];
              return o(n || r);
            },
            p,
            p.exports,
            r,
            e,
            n,
            t
          );
        }
        return n[i].exports;
      }
      for (
        var u = "function" == typeof require && require, i = 0;
        i < t.length;
        i++
      )
        o(t[i]);
      return o;
    }
    return r;
  })()(
    {
      1: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */

          "use strict";

          var _adapter_factory = require("./adapter_factory.js");

          var adapter = (0, _adapter_factory.adapterFactory)({
            window: typeof window === "undefined" ? undefined : window,
          });
          module.exports = adapter; // this is the difference from adapter_core.
        },
        { "./adapter_factory.js": 2 },
      ],
      2: [
        function (require, module, exports) {
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });
          exports.adapterFactory = adapterFactory;

          var _utils = require("./utils");

          var utils = _interopRequireWildcard(_utils);

          var _chrome_shim = require("./chrome/chrome_shim");

          var chromeShim = _interopRequireWildcard(_chrome_shim);

          var _firefox_shim = require("./firefox/firefox_shim");

          var firefoxShim = _interopRequireWildcard(_firefox_shim);

          var _safari_shim = require("./safari/safari_shim");

          var safariShim = _interopRequireWildcard(_safari_shim);

          var _common_shim = require("./common_shim");

          var commonShim = _interopRequireWildcard(_common_shim);

          var _sdp = require("sdp");

          var sdp = _interopRequireWildcard(_sdp);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          // Shimming starts here.
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          function adapterFactory() {
            var _ref =
                arguments.length > 0 && arguments[0] !== undefined
                  ? arguments[0]
                  : {},
              window = _ref.window;

            var options =
              arguments.length > 1 && arguments[1] !== undefined
                ? arguments[1]
                : {
                    shimChrome: true,
                    shimFirefox: true,
                    shimSafari: true,
                  };

            // Utils.
            var logging = utils.log;
            var browserDetails = utils.detectBrowser(window);

            var adapter = {
              browserDetails: browserDetails,
              commonShim: commonShim,
              extractVersion: utils.extractVersion,
              disableLog: utils.disableLog,
              disableWarnings: utils.disableWarnings,
              // Expose sdp as a convenience. For production apps include directly.
              sdp: sdp,
            };

            // Shim browser if found.
            switch (browserDetails.browser) {
              case "chrome":
                if (
                  !chromeShim ||
                  !chromeShim.shimPeerConnection ||
                  !options.shimChrome
                ) {
                  logging(
                    "Chrome shim is not included in this adapter release."
                  );
                  return adapter;
                }
                if (browserDetails.version === null) {
                  logging(
                    "Chrome shim can not determine version, not shimming."
                  );
                  return adapter;
                }
                logging("adapter.js shimming chrome.");
                // Export to the adapter global object visible in the browser.
                adapter.browserShim = chromeShim;

                // Must be called before shimPeerConnection.
                commonShim.shimAddIceCandidateNullOrEmpty(
                  window,
                  browserDetails
                );
                commonShim.shimParameterlessSetLocalDescription(
                  window,
                  browserDetails
                );

                chromeShim.shimGetUserMedia(window, browserDetails);
                chromeShim.shimMediaStream(window, browserDetails);
                chromeShim.shimPeerConnection(window, browserDetails);
                chromeShim.shimOnTrack(window, browserDetails);
                chromeShim.shimAddTrackRemoveTrack(window, browserDetails);
                chromeShim.shimGetSendersWithDtmf(window, browserDetails);
                chromeShim.shimGetStats(window, browserDetails);
                chromeShim.shimSenderReceiverGetStats(window, browserDetails);
                chromeShim.fixNegotiationNeeded(window, browserDetails);

                commonShim.shimRTCIceCandidate(window, browserDetails);
                commonShim.shimConnectionState(window, browserDetails);
                commonShim.shimMaxMessageSize(window, browserDetails);
                commonShim.shimSendThrowTypeError(window, browserDetails);
                commonShim.removeExtmapAllowMixed(window, browserDetails);
                break;
              case "firefox":
                if (
                  !firefoxShim ||
                  !firefoxShim.shimPeerConnection ||
                  !options.shimFirefox
                ) {
                  logging(
                    "Firefox shim is not included in this adapter release."
                  );
                  return adapter;
                }
                logging("adapter.js shimming firefox.");
                // Export to the adapter global object visible in the browser.
                adapter.browserShim = firefoxShim;

                // Must be called before shimPeerConnection.
                commonShim.shimAddIceCandidateNullOrEmpty(
                  window,
                  browserDetails
                );
                commonShim.shimParameterlessSetLocalDescription(
                  window,
                  browserDetails
                );

                firefoxShim.shimGetUserMedia(window, browserDetails);
                firefoxShim.shimPeerConnection(window, browserDetails);
                firefoxShim.shimOnTrack(window, browserDetails);
                firefoxShim.shimRemoveStream(window, browserDetails);
                firefoxShim.shimSenderGetStats(window, browserDetails);
                firefoxShim.shimReceiverGetStats(window, browserDetails);
                firefoxShim.shimRTCDataChannel(window, browserDetails);
                firefoxShim.shimAddTransceiver(window, browserDetails);
                firefoxShim.shimGetParameters(window, browserDetails);
                firefoxShim.shimCreateOffer(window, browserDetails);
                firefoxShim.shimCreateAnswer(window, browserDetails);

                commonShim.shimRTCIceCandidate(window, browserDetails);
                commonShim.shimConnectionState(window, browserDetails);
                commonShim.shimMaxMessageSize(window, browserDetails);
                commonShim.shimSendThrowTypeError(window, browserDetails);
                break;
              case "safari":
                if (!safariShim || !options.shimSafari) {
                  logging(
                    "Safari shim is not included in this adapter release."
                  );
                  return adapter;
                }
                logging("adapter.js shimming safari.");
                // Export to the adapter global object visible in the browser.
                adapter.browserShim = safariShim;

                // Must be called before shimCallbackAPI.
                commonShim.shimAddIceCandidateNullOrEmpty(
                  window,
                  browserDetails
                );
                commonShim.shimParameterlessSetLocalDescription(
                  window,
                  browserDetails
                );

                safariShim.shimRTCIceServerUrls(window, browserDetails);
                safariShim.shimCreateOfferLegacy(window, browserDetails);
                safariShim.shimCallbacksAPI(window, browserDetails);
                safariShim.shimLocalStreamsAPI(window, browserDetails);
                safariShim.shimRemoteStreamsAPI(window, browserDetails);
                safariShim.shimTrackEventTransceiver(window, browserDetails);
                safariShim.shimGetUserMedia(window, browserDetails);
                safariShim.shimAudioContext(window, browserDetails);

                commonShim.shimRTCIceCandidate(window, browserDetails);
                commonShim.shimMaxMessageSize(window, browserDetails);
                commonShim.shimSendThrowTypeError(window, browserDetails);
                commonShim.removeExtmapAllowMixed(window, browserDetails);
                break;
              default:
                logging("Unsupported browser!");
                break;
            }

            return adapter;
          }

          // Browser shims.
        },
        {
          "./chrome/chrome_shim": 3,
          "./common_shim": 6,
          "./firefox/firefox_shim": 7,
          "./safari/safari_shim": 10,
          "./utils": 11,
          sdp: 12,
        },
      ],
      3: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });
          exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          var _getusermedia = require("./getusermedia");

          Object.defineProperty(exports, "shimGetUserMedia", {
            enumerable: true,
            get: function get() {
              return _getusermedia.shimGetUserMedia;
            },
          });

          var _getdisplaymedia = require("./getdisplaymedia");

          Object.defineProperty(exports, "shimGetDisplayMedia", {
            enumerable: true,
            get: function get() {
              return _getdisplaymedia.shimGetDisplayMedia;
            },
          });
          exports.shimMediaStream = shimMediaStream;
          exports.shimOnTrack = shimOnTrack;
          exports.shimGetSendersWithDtmf = shimGetSendersWithDtmf;
          exports.shimGetStats = shimGetStats;
          exports.shimSenderReceiverGetStats = shimSenderReceiverGetStats;
          exports.shimAddTrackRemoveTrackWithNative =
            shimAddTrackRemoveTrackWithNative;
          exports.shimAddTrackRemoveTrack = shimAddTrackRemoveTrack;
          exports.shimPeerConnection = shimPeerConnection;
          exports.fixNegotiationNeeded = fixNegotiationNeeded;

          var _utils = require("../utils.js");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          function _defineProperty(obj, key, value) {
            if (key in obj) {
              Object.defineProperty(obj, key, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true,
              });
            } else {
              obj[key] = value;
            }
            return obj;
          }

          function shimMediaStream(window) {
            window.MediaStream = window.MediaStream || window.webkitMediaStream;
          }

          function shimOnTrack(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object" &&
              window.RTCPeerConnection &&
              !("ontrack" in window.RTCPeerConnection.prototype)
            ) {
              Object.defineProperty(
                window.RTCPeerConnection.prototype,
                "ontrack",
                {
                  get: function get() {
                    return this._ontrack;
                  },
                  set: function set(f) {
                    if (this._ontrack) {
                      this.removeEventListener("track", this._ontrack);
                    }
                    this.addEventListener("track", (this._ontrack = f));
                  },

                  enumerable: true,
                  configurable: true,
                }
              );
              var origSetRemoteDescription =
                window.RTCPeerConnection.prototype.setRemoteDescription;
              window.RTCPeerConnection.prototype.setRemoteDescription =
                function setRemoteDescription() {
                  var _this = this;

                  if (!this._ontrackpoly) {
                    this._ontrackpoly = function (e) {
                      // onaddstream does not fire when a track is added to an existing
                      // stream. But stream.onaddtrack is implemented so we use that.
                      e.stream.addEventListener("addtrack", function (te) {
                        var receiver = void 0;
                        if (window.RTCPeerConnection.prototype.getReceivers) {
                          receiver = _this.getReceivers().find(function (r) {
                            return r.track && r.track.id === te.track.id;
                          });
                        } else {
                          receiver = { track: te.track };
                        }

                        var event = new Event("track");
                        event.track = te.track;
                        event.receiver = receiver;
                        event.transceiver = { receiver: receiver };
                        event.streams = [e.stream];
                        _this.dispatchEvent(event);
                      });
                      e.stream.getTracks().forEach(function (track) {
                        var receiver = void 0;
                        if (window.RTCPeerConnection.prototype.getReceivers) {
                          receiver = _this.getReceivers().find(function (r) {
                            return r.track && r.track.id === track.id;
                          });
                        } else {
                          receiver = { track: track };
                        }
                        var event = new Event("track");
                        event.track = track;
                        event.receiver = receiver;
                        event.transceiver = { receiver: receiver };
                        event.streams = [e.stream];
                        _this.dispatchEvent(event);
                      });
                    };
                    this.addEventListener("addstream", this._ontrackpoly);
                  }
                  return origSetRemoteDescription.apply(this, arguments);
                };
            } else {
              // even if RTCRtpTransceiver is in window, it is only used and
              // emitted in unified-plan. Unfortunately this means we need
              // to unconditionally wrap the event.
              utils.wrapPeerConnectionEvent(window, "track", function (e) {
                if (!e.transceiver) {
                  Object.defineProperty(e, "transceiver", {
                    value: { receiver: e.receiver },
                  });
                }
                return e;
              });
            }
          }

          function shimGetSendersWithDtmf(window) {
            // Overrides addTrack/removeTrack, depends on shimAddTrackRemoveTrack.
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object" &&
              window.RTCPeerConnection &&
              !("getSenders" in window.RTCPeerConnection.prototype) &&
              "createDTMFSender" in window.RTCPeerConnection.prototype
            ) {
              var shimSenderWithDtmf = function shimSenderWithDtmf(pc, track) {
                return {
                  track: track,
                  get dtmf() {
                    if (this._dtmf === undefined) {
                      if (track.kind === "audio") {
                        this._dtmf = pc.createDTMFSender(track);
                      } else {
                        this._dtmf = null;
                      }
                    }
                    return this._dtmf;
                  },
                  _pc: pc,
                };
              };

              // augment addTrack when getSenders is not available.
              if (!window.RTCPeerConnection.prototype.getSenders) {
                window.RTCPeerConnection.prototype.getSenders =
                  function getSenders() {
                    this._senders = this._senders || [];
                    return this._senders.slice(); // return a copy of the internal state.
                  };
                var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
                window.RTCPeerConnection.prototype.addTrack = function addTrack(
                  track,
                  stream
                ) {
                  var sender = origAddTrack.apply(this, arguments);
                  if (!sender) {
                    sender = shimSenderWithDtmf(this, track);
                    this._senders.push(sender);
                  }
                  return sender;
                };

                var origRemoveTrack =
                  window.RTCPeerConnection.prototype.removeTrack;
                window.RTCPeerConnection.prototype.removeTrack =
                  function removeTrack(sender) {
                    origRemoveTrack.apply(this, arguments);
                    var idx = this._senders.indexOf(sender);
                    if (idx !== -1) {
                      this._senders.splice(idx, 1);
                    }
                  };
              }
              var origAddStream = window.RTCPeerConnection.prototype.addStream;
              window.RTCPeerConnection.prototype.addStream = function addStream(
                stream
              ) {
                var _this2 = this;

                this._senders = this._senders || [];
                origAddStream.apply(this, [stream]);
                stream.getTracks().forEach(function (track) {
                  _this2._senders.push(shimSenderWithDtmf(_this2, track));
                });
              };

              var origRemoveStream =
                window.RTCPeerConnection.prototype.removeStream;
              window.RTCPeerConnection.prototype.removeStream =
                function removeStream(stream) {
                  var _this3 = this;

                  this._senders = this._senders || [];
                  origRemoveStream.apply(this, [stream]);

                  stream.getTracks().forEach(function (track) {
                    var sender = _this3._senders.find(function (s) {
                      return s.track === track;
                    });
                    if (sender) {
                      // remove sender
                      _this3._senders.splice(
                        _this3._senders.indexOf(sender),
                        1
                      );
                    }
                  });
                };
            } else if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object" &&
              window.RTCPeerConnection &&
              "getSenders" in window.RTCPeerConnection.prototype &&
              "createDTMFSender" in window.RTCPeerConnection.prototype &&
              window.RTCRtpSender &&
              !("dtmf" in window.RTCRtpSender.prototype)
            ) {
              var origGetSenders =
                window.RTCPeerConnection.prototype.getSenders;
              window.RTCPeerConnection.prototype.getSenders =
                function getSenders() {
                  var _this4 = this;

                  var senders = origGetSenders.apply(this, []);
                  senders.forEach(function (sender) {
                    return (sender._pc = _this4);
                  });
                  return senders;
                };

              Object.defineProperty(window.RTCRtpSender.prototype, "dtmf", {
                get: function get() {
                  if (this._dtmf === undefined) {
                    if (this.track.kind === "audio") {
                      this._dtmf = this._pc.createDTMFSender(this.track);
                    } else {
                      this._dtmf = null;
                    }
                  }
                  return this._dtmf;
                },
              });
            }
          }

          function shimGetStats(window) {
            if (!window.RTCPeerConnection) {
              return;
            }

            var origGetStats = window.RTCPeerConnection.prototype.getStats;
            window.RTCPeerConnection.prototype.getStats = function getStats() {
              var _this5 = this;

              var _arguments = Array.prototype.slice.call(arguments),
                selector = _arguments[0],
                onSucc = _arguments[1],
                onErr = _arguments[2];

              // If selector is a function then we are in the old style stats so just
              // pass back the original getStats format to avoid breaking old users.

              if (arguments.length > 0 && typeof selector === "function") {
                return origGetStats.apply(this, arguments);
              }

              // When spec-style getStats is supported, return those when called with
              // either no arguments or the selector argument is null.
              if (
                origGetStats.length === 0 &&
                (arguments.length === 0 || typeof selector !== "function")
              ) {
                return origGetStats.apply(this, []);
              }

              var fixChromeStats_ = function fixChromeStats_(response) {
                var standardReport = {};
                var reports = response.result();
                reports.forEach(function (report) {
                  var standardStats = {
                    id: report.id,
                    timestamp: report.timestamp,
                    type:
                      {
                        localcandidate: "local-candidate",
                        remotecandidate: "remote-candidate",
                      }[report.type] || report.type,
                  };
                  report.names().forEach(function (name) {
                    standardStats[name] = report.stat(name);
                  });
                  standardReport[standardStats.id] = standardStats;
                });

                return standardReport;
              };

              // shim getStats with maplike support
              var makeMapStats = function makeMapStats(stats) {
                return new Map(
                  Object.keys(stats).map(function (key) {
                    return [key, stats[key]];
                  })
                );
              };

              if (arguments.length >= 2) {
                var successCallbackWrapper_ = function successCallbackWrapper_(
                  response
                ) {
                  onSucc(makeMapStats(fixChromeStats_(response)));
                };

                return origGetStats.apply(this, [
                  successCallbackWrapper_,
                  selector,
                ]);
              }

              // promise-support
              return new Promise(function (resolve, reject) {
                origGetStats.apply(_this5, [
                  function (response) {
                    resolve(makeMapStats(fixChromeStats_(response)));
                  },
                  reject,
                ]);
              }).then(onSucc, onErr);
            };
          }

          function shimSenderReceiverGetStats(window) {
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" &&
                window.RTCPeerConnection &&
                window.RTCRtpSender &&
                window.RTCRtpReceiver
              )
            ) {
              return;
            }

            // shim sender stats.
            if (!("getStats" in window.RTCRtpSender.prototype)) {
              var origGetSenders =
                window.RTCPeerConnection.prototype.getSenders;
              if (origGetSenders) {
                window.RTCPeerConnection.prototype.getSenders =
                  function getSenders() {
                    var _this6 = this;

                    var senders = origGetSenders.apply(this, []);
                    senders.forEach(function (sender) {
                      return (sender._pc = _this6);
                    });
                    return senders;
                  };
              }

              var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
              if (origAddTrack) {
                window.RTCPeerConnection.prototype.addTrack =
                  function addTrack() {
                    var sender = origAddTrack.apply(this, arguments);
                    sender._pc = this;
                    return sender;
                  };
              }
              window.RTCRtpSender.prototype.getStats = function getStats() {
                var sender = this;
                return this._pc.getStats().then(function (result) {
                  return (
                    /* Note: this will include stats of all senders that
                     *   send a track with the same id as sender.track as
                     *   it is not possible to identify the RTCRtpSender.
                     */
                    utils.filterStats(result, sender.track, true)
                  );
                });
              };
            }

            // shim receiver stats.
            if (!("getStats" in window.RTCRtpReceiver.prototype)) {
              var origGetReceivers =
                window.RTCPeerConnection.prototype.getReceivers;
              if (origGetReceivers) {
                window.RTCPeerConnection.prototype.getReceivers =
                  function getReceivers() {
                    var _this7 = this;

                    var receivers = origGetReceivers.apply(this, []);
                    receivers.forEach(function (receiver) {
                      return (receiver._pc = _this7);
                    });
                    return receivers;
                  };
              }
              utils.wrapPeerConnectionEvent(window, "track", function (e) {
                e.receiver._pc = e.srcElement;
                return e;
              });
              window.RTCRtpReceiver.prototype.getStats = function getStats() {
                var receiver = this;
                return this._pc.getStats().then(function (result) {
                  return utils.filterStats(result, receiver.track, false);
                });
              };
            }

            if (
              !(
                "getStats" in window.RTCRtpSender.prototype &&
                "getStats" in window.RTCRtpReceiver.prototype
              )
            ) {
              return;
            }

            // shim RTCPeerConnection.getStats(track).
            var origGetStats = window.RTCPeerConnection.prototype.getStats;
            window.RTCPeerConnection.prototype.getStats = function getStats() {
              if (
                arguments.length > 0 &&
                arguments[0] instanceof window.MediaStreamTrack
              ) {
                var track = arguments[0];
                var sender = void 0;
                var receiver = void 0;
                var err = void 0;
                this.getSenders().forEach(function (s) {
                  if (s.track === track) {
                    if (sender) {
                      err = true;
                    } else {
                      sender = s;
                    }
                  }
                });
                this.getReceivers().forEach(function (r) {
                  if (r.track === track) {
                    if (receiver) {
                      err = true;
                    } else {
                      receiver = r;
                    }
                  }
                  return r.track === track;
                });
                if (err || (sender && receiver)) {
                  return Promise.reject(
                    new DOMException(
                      "There are more than one sender or receiver for the track.",
                      "InvalidAccessError"
                    )
                  );
                } else if (sender) {
                  return sender.getStats();
                } else if (receiver) {
                  return receiver.getStats();
                }
                return Promise.reject(
                  new DOMException(
                    "There is no sender or receiver for the track.",
                    "InvalidAccessError"
                  )
                );
              }
              return origGetStats.apply(this, arguments);
            };
          }

          function shimAddTrackRemoveTrackWithNative(window) {
            // shim addTrack/removeTrack with native variants in order to make
            // the interactions with legacy getLocalStreams behave as in other browsers.
            // Keeps a mapping stream.id => [stream, rtpsenders...]
            window.RTCPeerConnection.prototype.getLocalStreams =
              function getLocalStreams() {
                var _this8 = this;

                this._shimmedLocalStreams = this._shimmedLocalStreams || {};
                return Object.keys(this._shimmedLocalStreams).map(function (
                  streamId
                ) {
                  return _this8._shimmedLocalStreams[streamId][0];
                });
              };

            var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
            window.RTCPeerConnection.prototype.addTrack = function addTrack(
              track,
              stream
            ) {
              if (!stream) {
                return origAddTrack.apply(this, arguments);
              }
              this._shimmedLocalStreams = this._shimmedLocalStreams || {};

              var sender = origAddTrack.apply(this, arguments);
              if (!this._shimmedLocalStreams[stream.id]) {
                this._shimmedLocalStreams[stream.id] = [stream, sender];
              } else if (
                this._shimmedLocalStreams[stream.id].indexOf(sender) === -1
              ) {
                this._shimmedLocalStreams[stream.id].push(sender);
              }
              return sender;
            };

            var origAddStream = window.RTCPeerConnection.prototype.addStream;
            window.RTCPeerConnection.prototype.addStream = function addStream(
              stream
            ) {
              var _this9 = this;

              this._shimmedLocalStreams = this._shimmedLocalStreams || {};

              stream.getTracks().forEach(function (track) {
                var alreadyExists = _this9.getSenders().find(function (s) {
                  return s.track === track;
                });
                if (alreadyExists) {
                  throw new DOMException(
                    "Track already exists.",
                    "InvalidAccessError"
                  );
                }
              });
              var existingSenders = this.getSenders();
              origAddStream.apply(this, arguments);
              var newSenders = this.getSenders().filter(function (newSender) {
                return existingSenders.indexOf(newSender) === -1;
              });
              this._shimmedLocalStreams[stream.id] = [stream].concat(
                newSenders
              );
            };

            var origRemoveStream =
              window.RTCPeerConnection.prototype.removeStream;
            window.RTCPeerConnection.prototype.removeStream =
              function removeStream(stream) {
                this._shimmedLocalStreams = this._shimmedLocalStreams || {};
                delete this._shimmedLocalStreams[stream.id];
                return origRemoveStream.apply(this, arguments);
              };

            var origRemoveTrack =
              window.RTCPeerConnection.prototype.removeTrack;
            window.RTCPeerConnection.prototype.removeTrack =
              function removeTrack(sender) {
                var _this10 = this;

                this._shimmedLocalStreams = this._shimmedLocalStreams || {};
                if (sender) {
                  Object.keys(this._shimmedLocalStreams).forEach(function (
                    streamId
                  ) {
                    var idx =
                      _this10._shimmedLocalStreams[streamId].indexOf(sender);
                    if (idx !== -1) {
                      _this10._shimmedLocalStreams[streamId].splice(idx, 1);
                    }
                    if (_this10._shimmedLocalStreams[streamId].length === 1) {
                      delete _this10._shimmedLocalStreams[streamId];
                    }
                  });
                }
                return origRemoveTrack.apply(this, arguments);
              };
          }

          function shimAddTrackRemoveTrack(window, browserDetails) {
            if (!window.RTCPeerConnection) {
              return;
            }
            // shim addTrack and removeTrack.
            if (
              window.RTCPeerConnection.prototype.addTrack &&
              browserDetails.version >= 65
            ) {
              return shimAddTrackRemoveTrackWithNative(window);
            }

            // also shim pc.getLocalStreams when addTrack is shimmed
            // to return the original streams.
            var origGetLocalStreams =
              window.RTCPeerConnection.prototype.getLocalStreams;
            window.RTCPeerConnection.prototype.getLocalStreams =
              function getLocalStreams() {
                var _this11 = this;

                var nativeStreams = origGetLocalStreams.apply(this);
                this._reverseStreams = this._reverseStreams || {};
                return nativeStreams.map(function (stream) {
                  return _this11._reverseStreams[stream.id];
                });
              };

            var origAddStream = window.RTCPeerConnection.prototype.addStream;
            window.RTCPeerConnection.prototype.addStream = function addStream(
              stream
            ) {
              var _this12 = this;

              this._streams = this._streams || {};
              this._reverseStreams = this._reverseStreams || {};

              stream.getTracks().forEach(function (track) {
                var alreadyExists = _this12.getSenders().find(function (s) {
                  return s.track === track;
                });
                if (alreadyExists) {
                  throw new DOMException(
                    "Track already exists.",
                    "InvalidAccessError"
                  );
                }
              });
              // Add identity mapping for consistency with addTrack.
              // Unless this is being used with a stream from addTrack.
              if (!this._reverseStreams[stream.id]) {
                var newStream = new window.MediaStream(stream.getTracks());
                this._streams[stream.id] = newStream;
                this._reverseStreams[newStream.id] = stream;
                stream = newStream;
              }
              origAddStream.apply(this, [stream]);
            };

            var origRemoveStream =
              window.RTCPeerConnection.prototype.removeStream;
            window.RTCPeerConnection.prototype.removeStream =
              function removeStream(stream) {
                this._streams = this._streams || {};
                this._reverseStreams = this._reverseStreams || {};

                origRemoveStream.apply(this, [
                  this._streams[stream.id] || stream,
                ]);
                delete this._reverseStreams[
                  this._streams[stream.id]
                    ? this._streams[stream.id].id
                    : stream.id
                ];
                delete this._streams[stream.id];
              };

            window.RTCPeerConnection.prototype.addTrack = function addTrack(
              track,
              stream
            ) {
              var _this13 = this;

              if (this.signalingState === "closed") {
                throw new DOMException(
                  "The RTCPeerConnection's signalingState is 'closed'.",
                  "InvalidStateError"
                );
              }
              var streams = [].slice.call(arguments, 1);
              if (
                streams.length !== 1 ||
                !streams[0].getTracks().find(function (t) {
                  return t === track;
                })
              ) {
                // this is not fully correct but all we can manage without
                // [[associated MediaStreams]] internal slot.
                throw new DOMException(
                  "The adapter.js addTrack polyfill only supports a single " +
                    " stream which is associated with the specified track.",
                  "NotSupportedError"
                );
              }

              var alreadyExists = this.getSenders().find(function (s) {
                return s.track === track;
              });
              if (alreadyExists) {
                throw new DOMException(
                  "Track already exists.",
                  "InvalidAccessError"
                );
              }

              this._streams = this._streams || {};
              this._reverseStreams = this._reverseStreams || {};
              var oldStream = this._streams[stream.id];
              if (oldStream) {
                // this is using odd Chrome behaviour, use with caution:
                // https://bugs.chromium.org/p/webrtc/issues/detail?id=7815
                // Note: we rely on the high-level addTrack/dtmf shim to
                // create the sender with a dtmf sender.
                oldStream.addTrack(track);

                // Trigger ONN async.
                Promise.resolve().then(function () {
                  _this13.dispatchEvent(new Event("negotiationneeded"));
                });
              } else {
                var newStream = new window.MediaStream([track]);
                this._streams[stream.id] = newStream;
                this._reverseStreams[newStream.id] = stream;
                this.addStream(newStream);
              }
              return this.getSenders().find(function (s) {
                return s.track === track;
              });
            };

            // replace the internal stream id with the external one and
            // vice versa.
            function replaceInternalStreamId(pc, description) {
              var sdp = description.sdp;
              Object.keys(pc._reverseStreams || []).forEach(function (
                internalId
              ) {
                var externalStream = pc._reverseStreams[internalId];
                var internalStream = pc._streams[externalStream.id];
                sdp = sdp.replace(
                  new RegExp(internalStream.id, "g"),
                  externalStream.id
                );
              });
              return new RTCSessionDescription({
                type: description.type,
                sdp: sdp,
              });
            }
            function replaceExternalStreamId(pc, description) {
              var sdp = description.sdp;
              Object.keys(pc._reverseStreams || []).forEach(function (
                internalId
              ) {
                var externalStream = pc._reverseStreams[internalId];
                var internalStream = pc._streams[externalStream.id];
                sdp = sdp.replace(
                  new RegExp(externalStream.id, "g"),
                  internalStream.id
                );
              });
              return new RTCSessionDescription({
                type: description.type,
                sdp: sdp,
              });
            }
            ["createOffer", "createAnswer"].forEach(function (method) {
              var nativeMethod = window.RTCPeerConnection.prototype[method];
              var methodObj = _defineProperty({}, method, function () {
                var _this14 = this;

                var args = arguments;
                var isLegacyCall =
                  arguments.length && typeof arguments[0] === "function";
                if (isLegacyCall) {
                  return nativeMethod.apply(this, [
                    function (description) {
                      var desc = replaceInternalStreamId(_this14, description);
                      args[0].apply(null, [desc]);
                    },
                    function (err) {
                      if (args[1]) {
                        args[1].apply(null, err);
                      }
                    },
                    arguments[2],
                  ]);
                }
                return nativeMethod
                  .apply(this, arguments)
                  .then(function (description) {
                    return replaceInternalStreamId(_this14, description);
                  });
              });
              window.RTCPeerConnection.prototype[method] = methodObj[method];
            });

            var origSetLocalDescription =
              window.RTCPeerConnection.prototype.setLocalDescription;
            window.RTCPeerConnection.prototype.setLocalDescription =
              function setLocalDescription() {
                if (!arguments.length || !arguments[0].type) {
                  return origSetLocalDescription.apply(this, arguments);
                }
                arguments[0] = replaceExternalStreamId(this, arguments[0]);
                return origSetLocalDescription.apply(this, arguments);
              };

            // TODO: mangle getStats: https://w3c.github.io/webrtc-stats/#dom-rtcmediastreamstats-streamidentifier

            var origLocalDescription = Object.getOwnPropertyDescriptor(
              window.RTCPeerConnection.prototype,
              "localDescription"
            );
            Object.defineProperty(
              window.RTCPeerConnection.prototype,
              "localDescription",
              {
                get: function get() {
                  var description = origLocalDescription.get.apply(this);
                  if (description.type === "") {
                    return description;
                  }
                  return replaceInternalStreamId(this, description);
                },
              }
            );

            window.RTCPeerConnection.prototype.removeTrack =
              function removeTrack(sender) {
                var _this15 = this;

                if (this.signalingState === "closed") {
                  throw new DOMException(
                    "The RTCPeerConnection's signalingState is 'closed'.",
                    "InvalidStateError"
                  );
                }
                // We can not yet check for sender instanceof RTCRtpSender
                // since we shim RTPSender. So we check if sender._pc is set.
                if (!sender._pc) {
                  throw new DOMException(
                    "Argument 1 of RTCPeerConnection.removeTrack " +
                      "does not implement interface RTCRtpSender.",
                    "TypeError"
                  );
                }
                var isLocal = sender._pc === this;
                if (!isLocal) {
                  throw new DOMException(
                    "Sender was not created by this connection.",
                    "InvalidAccessError"
                  );
                }

                // Search for the native stream the senders track belongs to.
                this._streams = this._streams || {};
                var stream = void 0;
                Object.keys(this._streams).forEach(function (streamid) {
                  var hasTrack = _this15._streams[streamid]
                    .getTracks()
                    .find(function (track) {
                      return sender.track === track;
                    });
                  if (hasTrack) {
                    stream = _this15._streams[streamid];
                  }
                });

                if (stream) {
                  if (stream.getTracks().length === 1) {
                    // if this is the last track of the stream, remove the stream. This
                    // takes care of any shimmed _senders.
                    this.removeStream(this._reverseStreams[stream.id]);
                  } else {
                    // relying on the same odd chrome behaviour as above.
                    stream.removeTrack(sender.track);
                  }
                  this.dispatchEvent(new Event("negotiationneeded"));
                }
              };
          }

          function shimPeerConnection(window, browserDetails) {
            if (!window.RTCPeerConnection && window.webkitRTCPeerConnection) {
              // very basic support for old versions.
              window.RTCPeerConnection = window.webkitRTCPeerConnection;
            }
            if (!window.RTCPeerConnection) {
              return;
            }

            // shim implicit creation of RTCSessionDescription/RTCIceCandidate
            if (browserDetails.version < 53) {
              [
                "setLocalDescription",
                "setRemoteDescription",
                "addIceCandidate",
              ].forEach(function (method) {
                var nativeMethod = window.RTCPeerConnection.prototype[method];
                var methodObj = _defineProperty({}, method, function () {
                  arguments[0] = new (
                    method === "addIceCandidate"
                      ? window.RTCIceCandidate
                      : window.RTCSessionDescription
                  )(arguments[0]);
                  return nativeMethod.apply(this, arguments);
                });
                window.RTCPeerConnection.prototype[method] = methodObj[method];
              });
            }
          }

          // Attempt to fix ONN in plan-b mode.
          function fixNegotiationNeeded(window, browserDetails) {
            utils.wrapPeerConnectionEvent(
              window,
              "negotiationneeded",
              function (e) {
                var pc = e.target;
                if (
                  browserDetails.version < 72 ||
                  (pc.getConfiguration &&
                    pc.getConfiguration().sdpSemantics === "plan-b")
                ) {
                  if (pc.signalingState !== "stable") {
                    return;
                  }
                }
                return e;
              }
            );
          }
        },
        { "../utils.js": 11, "./getdisplaymedia": 4, "./getusermedia": 5 },
      ],
      4: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });
          exports.shimGetDisplayMedia = shimGetDisplayMedia;
          function shimGetDisplayMedia(window, getSourceId) {
            if (
              window.navigator.mediaDevices &&
              "getDisplayMedia" in window.navigator.mediaDevices
            ) {
              return;
            }
            if (!window.navigator.mediaDevices) {
              return;
            }
            // getSourceId is a function that returns a promise resolving with
            // the sourceId of the screen/window/tab to be shared.
            if (typeof getSourceId !== "function") {
              console.error(
                "shimGetDisplayMedia: getSourceId argument is not " +
                  "a function"
              );
              return;
            }
            window.navigator.mediaDevices.getDisplayMedia =
              function getDisplayMedia(constraints) {
                return getSourceId(constraints).then(function (sourceId) {
                  var widthSpecified =
                    constraints.video && constraints.video.width;
                  var heightSpecified =
                    constraints.video && constraints.video.height;
                  var frameRateSpecified =
                    constraints.video && constraints.video.frameRate;
                  constraints.video = {
                    mandatory: {
                      chromeMediaSource: "desktop",
                      chromeMediaSourceId: sourceId,
                      maxFrameRate: frameRateSpecified || 3,
                    },
                  };
                  if (widthSpecified) {
                    constraints.video.mandatory.maxWidth = widthSpecified;
                  }
                  if (heightSpecified) {
                    constraints.video.mandatory.maxHeight = heightSpecified;
                  }
                  return window.navigator.mediaDevices.getUserMedia(
                    constraints
                  );
                });
              };
          }
        },
        {},
      ],
      5: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          exports.shimGetUserMedia = shimGetUserMedia;

          var _utils = require("../utils.js");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          var logging = utils.log;

          function shimGetUserMedia(window, browserDetails) {
            var navigator = window && window.navigator;

            if (!navigator.mediaDevices) {
              return;
            }

            var constraintsToChrome_ = function constraintsToChrome_(c) {
              if (
                (typeof c === "undefined" ? "undefined" : _typeof(c)) !==
                  "object" ||
                c.mandatory ||
                c.optional
              ) {
                return c;
              }
              var cc = {};
              Object.keys(c).forEach(function (key) {
                if (
                  key === "require" ||
                  key === "advanced" ||
                  key === "mediaSource"
                ) {
                  return;
                }
                var r =
                  _typeof(c[key]) === "object" ? c[key] : { ideal: c[key] };
                if (r.exact !== undefined && typeof r.exact === "number") {
                  r.min = r.max = r.exact;
                }
                var oldname_ = function oldname_(prefix, name) {
                  if (prefix) {
                    return (
                      prefix + name.charAt(0).toUpperCase() + name.slice(1)
                    );
                  }
                  return name === "deviceId" ? "sourceId" : name;
                };
                if (r.ideal !== undefined) {
                  cc.optional = cc.optional || [];
                  var oc = {};
                  if (typeof r.ideal === "number") {
                    oc[oldname_("min", key)] = r.ideal;
                    cc.optional.push(oc);
                    oc = {};
                    oc[oldname_("max", key)] = r.ideal;
                    cc.optional.push(oc);
                  } else {
                    oc[oldname_("", key)] = r.ideal;
                    cc.optional.push(oc);
                  }
                }
                if (r.exact !== undefined && typeof r.exact !== "number") {
                  cc.mandatory = cc.mandatory || {};
                  cc.mandatory[oldname_("", key)] = r.exact;
                } else {
                  ["min", "max"].forEach(function (mix) {
                    if (r[mix] !== undefined) {
                      cc.mandatory = cc.mandatory || {};
                      cc.mandatory[oldname_(mix, key)] = r[mix];
                    }
                  });
                }
              });
              if (c.advanced) {
                cc.optional = (cc.optional || []).concat(c.advanced);
              }
              return cc;
            };

            var shimConstraints_ = function shimConstraints_(
              constraints,
              func
            ) {
              if (browserDetails.version >= 61) {
                return func(constraints);
              }
              constraints = JSON.parse(JSON.stringify(constraints));
              if (constraints && _typeof(constraints.audio) === "object") {
                var remap = function remap(obj, a, b) {
                  if (a in obj && !(b in obj)) {
                    obj[b] = obj[a];
                    delete obj[a];
                  }
                };
                constraints = JSON.parse(JSON.stringify(constraints));
                remap(
                  constraints.audio,
                  "autoGainControl",
                  "googAutoGainControl"
                );
                remap(
                  constraints.audio,
                  "noiseSuppression",
                  "googNoiseSuppression"
                );
                constraints.audio = constraintsToChrome_(constraints.audio);
              }
              if (constraints && _typeof(constraints.video) === "object") {
                // Shim facingMode for mobile & surface pro.
                var face = constraints.video.facingMode;
                face =
                  face &&
                  ((typeof face === "undefined"
                    ? "undefined"
                    : _typeof(face)) === "object"
                    ? face
                    : { ideal: face });
                var getSupportedFacingModeLies = browserDetails.version < 66;

                if (
                  face &&
                  (face.exact === "user" ||
                    face.exact === "environment" ||
                    face.ideal === "user" ||
                    face.ideal === "environment") &&
                  !(
                    navigator.mediaDevices.getSupportedConstraints &&
                    navigator.mediaDevices.getSupportedConstraints()
                      .facingMode &&
                    !getSupportedFacingModeLies
                  )
                ) {
                  delete constraints.video.facingMode;
                  var matches = void 0;
                  if (
                    face.exact === "environment" ||
                    face.ideal === "environment"
                  ) {
                    matches = ["back", "rear"];
                  } else if (face.exact === "user" || face.ideal === "user") {
                    matches = ["front"];
                  }
                  if (matches) {
                    // Look for matches in label, or use last cam for back (typical).
                    return navigator.mediaDevices
                      .enumerateDevices()
                      .then(function (devices) {
                        devices = devices.filter(function (d) {
                          return d.kind === "videoinput";
                        });
                        var dev = devices.find(function (d) {
                          return matches.some(function (match) {
                            return d.label.toLowerCase().includes(match);
                          });
                        });
                        if (
                          !dev &&
                          devices.length &&
                          matches.includes("back")
                        ) {
                          dev = devices[devices.length - 1]; // more likely the back cam
                        }
                        if (dev) {
                          constraints.video.deviceId = face.exact
                            ? { exact: dev.deviceId }
                            : { ideal: dev.deviceId };
                        }
                        constraints.video = constraintsToChrome_(
                          constraints.video
                        );
                        logging("chrome: " + JSON.stringify(constraints));
                        return func(constraints);
                      });
                  }
                }
                constraints.video = constraintsToChrome_(constraints.video);
              }
              logging("chrome: " + JSON.stringify(constraints));
              return func(constraints);
            };

            var shimError_ = function shimError_(e) {
              if (browserDetails.version >= 64) {
                return e;
              }
              return {
                name:
                  {
                    PermissionDeniedError: "NotAllowedError",
                    PermissionDismissedError: "NotAllowedError",
                    InvalidStateError: "NotAllowedError",
                    DevicesNotFoundError: "NotFoundError",
                    ConstraintNotSatisfiedError: "OverconstrainedError",
                    TrackStartError: "NotReadableError",
                    MediaDeviceFailedDueToShutdown: "NotAllowedError",
                    MediaDeviceKillSwitchOn: "NotAllowedError",
                    TabCaptureError: "AbortError",
                    ScreenCaptureError: "AbortError",
                    DeviceCaptureError: "AbortError",
                  }[e.name] || e.name,
                message: e.message,
                constraint: e.constraint || e.constraintName,
                toString: function toString() {
                  return this.name + (this.message && ": ") + this.message;
                },
              };
            };

            var getUserMedia_ = function getUserMedia_(
              constraints,
              onSuccess,
              onError
            ) {
              shimConstraints_(constraints, function (c) {
                navigator.webkitGetUserMedia(c, onSuccess, function (e) {
                  if (onError) {
                    onError(shimError_(e));
                  }
                });
              });
            };
            navigator.getUserMedia = getUserMedia_.bind(navigator);

            // Even though Chrome 45 has navigator.mediaDevices and a getUserMedia
            // function which returns a Promise, it does not accept spec-style
            // constraints.
            if (navigator.mediaDevices.getUserMedia) {
              var origGetUserMedia = navigator.mediaDevices.getUserMedia.bind(
                navigator.mediaDevices
              );
              navigator.mediaDevices.getUserMedia = function (cs) {
                return shimConstraints_(cs, function (c) {
                  return origGetUserMedia(c).then(
                    function (stream) {
                      if (
                        (c.audio && !stream.getAudioTracks().length) ||
                        (c.video && !stream.getVideoTracks().length)
                      ) {
                        stream.getTracks().forEach(function (track) {
                          track.stop();
                        });
                        throw new DOMException("", "NotFoundError");
                      }
                      return stream;
                    },
                    function (e) {
                      return Promise.reject(shimError_(e));
                    }
                  );
                });
              };
            }
          }
        },
        { "../utils.js": 11 },
      ],
      6: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          exports.shimRTCIceCandidate = shimRTCIceCandidate;
          exports.shimMaxMessageSize = shimMaxMessageSize;
          exports.shimSendThrowTypeError = shimSendThrowTypeError;
          exports.shimConnectionState = shimConnectionState;
          exports.removeExtmapAllowMixed = removeExtmapAllowMixed;
          exports.shimAddIceCandidateNullOrEmpty =
            shimAddIceCandidateNullOrEmpty;
          exports.shimParameterlessSetLocalDescription =
            shimParameterlessSetLocalDescription;

          var _sdp = require("sdp");

          var _sdp2 = _interopRequireDefault(_sdp);

          var _utils = require("./utils");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          function _interopRequireDefault(obj) {
            return obj && obj.__esModule ? obj : { default: obj };
          }

          function shimRTCIceCandidate(window) {
            // foundation is arbitrarily chosen as an indicator for full support for
            // https://w3c.github.io/webrtc-pc/#rtcicecandidate-interface
            if (
              !window.RTCIceCandidate ||
              (window.RTCIceCandidate &&
                "foundation" in window.RTCIceCandidate.prototype)
            ) {
              return;
            }

            var NativeRTCIceCandidate = window.RTCIceCandidate;
            window.RTCIceCandidate = function RTCIceCandidate(args) {
              // Remove the a= which shouldn't be part of the candidate string.
              if (
                (typeof args === "undefined" ? "undefined" : _typeof(args)) ===
                  "object" &&
                args.candidate &&
                args.candidate.indexOf("a=") === 0
              ) {
                args = JSON.parse(JSON.stringify(args));
                args.candidate = args.candidate.substr(2);
              }

              if (args.candidate && args.candidate.length) {
                // Augment the native candidate with the parsed fields.
                var nativeCandidate = new NativeRTCIceCandidate(args);
                var parsedCandidate = _sdp2.default.parseCandidate(
                  args.candidate
                );
                var augmentedCandidate = Object.assign(
                  nativeCandidate,
                  parsedCandidate
                );

                // Add a serializer that does not serialize the extra attributes.
                augmentedCandidate.toJSON = function toJSON() {
                  return {
                    candidate: augmentedCandidate.candidate,
                    sdpMid: augmentedCandidate.sdpMid,
                    sdpMLineIndex: augmentedCandidate.sdpMLineIndex,
                    usernameFragment: augmentedCandidate.usernameFragment,
                  };
                };
                return augmentedCandidate;
              }
              return new NativeRTCIceCandidate(args);
            };
            window.RTCIceCandidate.prototype = NativeRTCIceCandidate.prototype;

            // Hook up the augmented candidate in onicecandidate and
            // addEventListener('icecandidate', ...)
            utils.wrapPeerConnectionEvent(window, "icecandidate", function (e) {
              if (e.candidate) {
                Object.defineProperty(e, "candidate", {
                  value: new window.RTCIceCandidate(e.candidate),
                  writable: "false",
                });
              }
              return e;
            });
          }

          function shimMaxMessageSize(window, browserDetails) {
            if (!window.RTCPeerConnection) {
              return;
            }

            if (!("sctp" in window.RTCPeerConnection.prototype)) {
              Object.defineProperty(
                window.RTCPeerConnection.prototype,
                "sctp",
                {
                  get: function get() {
                    return typeof this._sctp === "undefined"
                      ? null
                      : this._sctp;
                  },
                }
              );
            }

            var sctpInDescription = function sctpInDescription(description) {
              if (!description || !description.sdp) {
                return false;
              }
              var sections = _sdp2.default.splitSections(description.sdp);
              sections.shift();
              return sections.some(function (mediaSection) {
                var mLine = _sdp2.default.parseMLine(mediaSection);
                return (
                  mLine &&
                  mLine.kind === "application" &&
                  mLine.protocol.indexOf("SCTP") !== -1
                );
              });
            };

            var getRemoteFirefoxVersion = function getRemoteFirefoxVersion(
              description
            ) {
              // TODO: Is there a better solution for detecting Firefox?
              var match = description.sdp.match(
                /mozilla...THIS_IS_SDPARTA-(\d+)/
              );
              if (match === null || match.length < 2) {
                return -1;
              }
              var version = parseInt(match[1], 10);
              // Test for NaN (yes, this is ugly)
              return version !== version ? -1 : version;
            };

            var getCanSendMaxMessageSize = function getCanSendMaxMessageSize(
              remoteIsFirefox
            ) {
              // Every implementation we know can send at least 64 KiB.
              // Note: Although Chrome is technically able to send up to 256 KiB, the
              //       data does not reach the other peer reliably.
              //       See: https://bugs.chromium.org/p/webrtc/issues/detail?id=8419
              var canSendMaxMessageSize = 65536;
              if (browserDetails.browser === "firefox") {
                if (browserDetails.version < 57) {
                  if (remoteIsFirefox === -1) {
                    // FF < 57 will send in 16 KiB chunks using the deprecated PPID
                    // fragmentation.
                    canSendMaxMessageSize = 16384;
                  } else {
                    // However, other FF (and RAWRTC) can reassemble PPID-fragmented
                    // messages. Thus, supporting ~2 GiB when sending.
                    canSendMaxMessageSize = 2147483637;
                  }
                } else if (browserDetails.version < 60) {
                  // Currently, all FF >= 57 will reset the remote maximum message size
                  // to the default value when a data channel is created at a later
                  // stage. :(
                  // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831
                  canSendMaxMessageSize =
                    browserDetails.version === 57 ? 65535 : 65536;
                } else {
                  // FF >= 60 supports sending ~2 GiB
                  canSendMaxMessageSize = 2147483637;
                }
              }
              return canSendMaxMessageSize;
            };

            var getMaxMessageSize = function getMaxMessageSize(
              description,
              remoteIsFirefox
            ) {
              // Note: 65536 bytes is the default value from the SDP spec. Also,
              //       every implementation we know supports receiving 65536 bytes.
              var maxMessageSize = 65536;

              // FF 57 has a slightly incorrect default remote max message size, so
              // we need to adjust it here to avoid a failure when sending.
              // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1425697
              if (
                browserDetails.browser === "firefox" &&
                browserDetails.version === 57
              ) {
                maxMessageSize = 65535;
              }

              var match = _sdp2.default.matchPrefix(
                description.sdp,
                "a=max-message-size:"
              );
              if (match.length > 0) {
                maxMessageSize = parseInt(match[0].substr(19), 10);
              } else if (
                browserDetails.browser === "firefox" &&
                remoteIsFirefox !== -1
              ) {
                // If the maximum message size is not present in the remote SDP and
                // both local and remote are Firefox, the remote peer can receive
                // ~2 GiB.
                maxMessageSize = 2147483637;
              }
              return maxMessageSize;
            };

            var origSetRemoteDescription =
              window.RTCPeerConnection.prototype.setRemoteDescription;
            window.RTCPeerConnection.prototype.setRemoteDescription =
              function setRemoteDescription() {
                this._sctp = null;
                // Chrome decided to not expose .sctp in plan-b mode.
                // As usual, adapter.js has to do an 'ugly worakaround'
                // to cover up the mess.
                if (
                  browserDetails.browser === "chrome" &&
                  browserDetails.version >= 76
                ) {
                  var _getConfiguration = this.getConfiguration(),
                    sdpSemantics = _getConfiguration.sdpSemantics;

                  if (sdpSemantics === "plan-b") {
                    Object.defineProperty(this, "sctp", {
                      get: function get() {
                        return typeof this._sctp === "undefined"
                          ? null
                          : this._sctp;
                      },

                      enumerable: true,
                      configurable: true,
                    });
                  }
                }

                if (sctpInDescription(arguments[0])) {
                  // Check if the remote is FF.
                  var isFirefox = getRemoteFirefoxVersion(arguments[0]);

                  // Get the maximum message size the local peer is capable of sending
                  var canSendMMS = getCanSendMaxMessageSize(isFirefox);

                  // Get the maximum message size of the remote peer.
                  var remoteMMS = getMaxMessageSize(arguments[0], isFirefox);

                  // Determine final maximum message size
                  var maxMessageSize = void 0;
                  if (canSendMMS === 0 && remoteMMS === 0) {
                    maxMessageSize = Number.POSITIVE_INFINITY;
                  } else if (canSendMMS === 0 || remoteMMS === 0) {
                    maxMessageSize = Math.max(canSendMMS, remoteMMS);
                  } else {
                    maxMessageSize = Math.min(canSendMMS, remoteMMS);
                  }

                  // Create a dummy RTCSctpTransport object and the 'maxMessageSize'
                  // attribute.
                  var sctp = {};
                  Object.defineProperty(sctp, "maxMessageSize", {
                    get: function get() {
                      return maxMessageSize;
                    },
                  });
                  this._sctp = sctp;
                }

                return origSetRemoteDescription.apply(this, arguments);
              };
          }

          function shimSendThrowTypeError(window) {
            if (
              !(
                window.RTCPeerConnection &&
                "createDataChannel" in window.RTCPeerConnection.prototype
              )
            ) {
              return;
            }

            // Note: Although Firefox >= 57 has a native implementation, the maximum
            //       message size can be reset for all data channels at a later stage.
            //       See: https://bugzilla.mozilla.org/show_bug.cgi?id=1426831

            function wrapDcSend(dc, pc) {
              var origDataChannelSend = dc.send;
              dc.send = function send() {
                var data = arguments[0];
                var length = data.length || data.size || data.byteLength;
                if (
                  dc.readyState === "open" &&
                  pc.sctp &&
                  length > pc.sctp.maxMessageSize
                ) {
                  throw new TypeError(
                    "Message too large (can send a maximum of " +
                      pc.sctp.maxMessageSize +
                      " bytes)"
                  );
                }
                return origDataChannelSend.apply(dc, arguments);
              };
            }
            var origCreateDataChannel =
              window.RTCPeerConnection.prototype.createDataChannel;
            window.RTCPeerConnection.prototype.createDataChannel =
              function createDataChannel() {
                var dataChannel = origCreateDataChannel.apply(this, arguments);
                wrapDcSend(dataChannel, this);
                return dataChannel;
              };
            utils.wrapPeerConnectionEvent(window, "datachannel", function (e) {
              wrapDcSend(e.channel, e.target);
              return e;
            });
          }

          /* shims RTCConnectionState by pretending it is the same as iceConnectionState.
           * See https://bugs.chromium.org/p/webrtc/issues/detail?id=6145#c12
           * for why this is a valid hack in Chrome. In Firefox it is slightly incorrect
           * since DTLS failures would be hidden. See
           * https://bugzilla.mozilla.org/show_bug.cgi?id=1265827
           * for the Firefox tracking bug.
           */
          function shimConnectionState(window) {
            if (
              !window.RTCPeerConnection ||
              "connectionState" in window.RTCPeerConnection.prototype
            ) {
              return;
            }
            var proto = window.RTCPeerConnection.prototype;
            Object.defineProperty(proto, "connectionState", {
              get: function get() {
                return (
                  {
                    completed: "connected",
                    checking: "connecting",
                  }[this.iceConnectionState] || this.iceConnectionState
                );
              },

              enumerable: true,
              configurable: true,
            });
            Object.defineProperty(proto, "onconnectionstatechange", {
              get: function get() {
                return this._onconnectionstatechange || null;
              },
              set: function set(cb) {
                if (this._onconnectionstatechange) {
                  this.removeEventListener(
                    "connectionstatechange",
                    this._onconnectionstatechange
                  );
                  delete this._onconnectionstatechange;
                }
                if (cb) {
                  this.addEventListener(
                    "connectionstatechange",
                    (this._onconnectionstatechange = cb)
                  );
                }
              },

              enumerable: true,
              configurable: true,
            });

            ["setLocalDescription", "setRemoteDescription"].forEach(function (
              method
            ) {
              var origMethod = proto[method];
              proto[method] = function () {
                if (!this._connectionstatechangepoly) {
                  this._connectionstatechangepoly = function (e) {
                    var pc = e.target;
                    if (pc._lastConnectionState !== pc.connectionState) {
                      pc._lastConnectionState = pc.connectionState;
                      var newEvent = new Event("connectionstatechange", e);
                      pc.dispatchEvent(newEvent);
                    }
                    return e;
                  };
                  this.addEventListener(
                    "iceconnectionstatechange",
                    this._connectionstatechangepoly
                  );
                }
                return origMethod.apply(this, arguments);
              };
            });
          }

          function removeExtmapAllowMixed(window, browserDetails) {
            /* remove a=extmap-allow-mixed for webrtc.org < M71 */
            if (!window.RTCPeerConnection) {
              return;
            }
            if (
              browserDetails.browser === "chrome" &&
              browserDetails.version >= 71
            ) {
              return;
            }
            if (
              browserDetails.browser === "safari" &&
              browserDetails.version >= 605
            ) {
              return;
            }
            var nativeSRD =
              window.RTCPeerConnection.prototype.setRemoteDescription;
            window.RTCPeerConnection.prototype.setRemoteDescription =
              function setRemoteDescription(desc) {
                if (
                  desc &&
                  desc.sdp &&
                  desc.sdp.indexOf("\na=extmap-allow-mixed") !== -1
                ) {
                  var sdp = desc.sdp
                    .split("\n")
                    .filter(function (line) {
                      return line.trim() !== "a=extmap-allow-mixed";
                    })
                    .join("\n");
                  // Safari enforces read-only-ness of RTCSessionDescription fields.
                  if (
                    window.RTCSessionDescription &&
                    desc instanceof window.RTCSessionDescription
                  ) {
                    arguments[0] = new window.RTCSessionDescription({
                      type: desc.type,
                      sdp: sdp,
                    });
                  } else {
                    desc.sdp = sdp;
                  }
                }
                return nativeSRD.apply(this, arguments);
              };
          }

          function shimAddIceCandidateNullOrEmpty(window, browserDetails) {
            // Support for addIceCandidate(null or undefined)
            // as well as addIceCandidate({candidate: "", ...})
            // https://bugs.chromium.org/p/chromium/issues/detail?id=978582
            // Note: must be called before other polyfills which change the signature.
            if (
              !(window.RTCPeerConnection && window.RTCPeerConnection.prototype)
            ) {
              return;
            }
            var nativeAddIceCandidate =
              window.RTCPeerConnection.prototype.addIceCandidate;
            if (!nativeAddIceCandidate || nativeAddIceCandidate.length === 0) {
              return;
            }
            window.RTCPeerConnection.prototype.addIceCandidate =
              function addIceCandidate() {
                if (!arguments[0]) {
                  if (arguments[1]) {
                    arguments[1].apply(null);
                  }
                  return Promise.resolve();
                }
                // Firefox 68+ emits and processes {candidate: "", ...}, ignore
                // in older versions.
                // Native support for ignoring exists for Chrome M77+.
                // Safari ignores as well, exact version unknown but works in the same
                // version that also ignores addIceCandidate(null).
                if (
                  ((browserDetails.browser === "chrome" &&
                    browserDetails.version < 78) ||
                    (browserDetails.browser === "firefox" &&
                      browserDetails.version < 68) ||
                    browserDetails.browser === "safari") &&
                  arguments[0] &&
                  arguments[0].candidate === ""
                ) {
                  return Promise.resolve();
                }
                return nativeAddIceCandidate.apply(this, arguments);
              };
          }

          // Note: Make sure to call this ahead of APIs that modify
          // setLocalDescription.length
          function shimParameterlessSetLocalDescription(
            window,
            browserDetails
          ) {
            if (
              !(window.RTCPeerConnection && window.RTCPeerConnection.prototype)
            ) {
              return;
            }
            var nativeSetLocalDescription =
              window.RTCPeerConnection.prototype.setLocalDescription;
            if (
              !nativeSetLocalDescription ||
              nativeSetLocalDescription.length === 0
            ) {
              return;
            }
            window.RTCPeerConnection.prototype.setLocalDescription =
              function setLocalDescription() {
                var _this = this;

                var desc = arguments[0] || {};
                if (
                  (typeof desc === "undefined"
                    ? "undefined"
                    : _typeof(desc)) !== "object" ||
                  (desc.type && desc.sdp)
                ) {
                  return nativeSetLocalDescription.apply(this, arguments);
                }
                // The remaining steps should technically happen when SLD comes off the
                // RTCPeerConnection's operations chain (not ahead of going on it), but
                // this is too difficult to shim. Instead, this shim only covers the
                // common case where the operations chain is empty. This is imperfect, but
                // should cover many cases. Rationale: Even if we can't reduce the glare
                // window to zero on imperfect implementations, there's value in tapping
                // into the perfect negotiation pattern that several browsers support.
                desc = { type: desc.type, sdp: desc.sdp };
                if (!desc.type) {
                  switch (this.signalingState) {
                    case "stable":
                    case "have-local-offer":
                    case "have-remote-pranswer":
                      desc.type = "offer";
                      break;
                    default:
                      desc.type = "answer";
                      break;
                  }
                }
                if (
                  desc.sdp ||
                  (desc.type !== "offer" && desc.type !== "answer")
                ) {
                  return nativeSetLocalDescription.apply(this, [desc]);
                }
                var func =
                  desc.type === "offer" ? this.createOffer : this.createAnswer;
                return func.apply(this).then(function (d) {
                  return nativeSetLocalDescription.apply(_this, [d]);
                });
              };
          }
        },
        { "./utils": 11, sdp: 12 },
      ],
      7: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });
          exports.shimGetDisplayMedia = exports.shimGetUserMedia = undefined;

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          var _getusermedia = require("./getusermedia");

          Object.defineProperty(exports, "shimGetUserMedia", {
            enumerable: true,
            get: function get() {
              return _getusermedia.shimGetUserMedia;
            },
          });

          var _getdisplaymedia = require("./getdisplaymedia");

          Object.defineProperty(exports, "shimGetDisplayMedia", {
            enumerable: true,
            get: function get() {
              return _getdisplaymedia.shimGetDisplayMedia;
            },
          });
          exports.shimOnTrack = shimOnTrack;
          exports.shimPeerConnection = shimPeerConnection;
          exports.shimSenderGetStats = shimSenderGetStats;
          exports.shimReceiverGetStats = shimReceiverGetStats;
          exports.shimRemoveStream = shimRemoveStream;
          exports.shimRTCDataChannel = shimRTCDataChannel;
          exports.shimAddTransceiver = shimAddTransceiver;
          exports.shimGetParameters = shimGetParameters;
          exports.shimCreateOffer = shimCreateOffer;
          exports.shimCreateAnswer = shimCreateAnswer;

          var _utils = require("../utils");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          function _defineProperty(obj, key, value) {
            if (key in obj) {
              Object.defineProperty(obj, key, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true,
              });
            } else {
              obj[key] = value;
            }
            return obj;
          }

          function shimOnTrack(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object" &&
              window.RTCTrackEvent &&
              "receiver" in window.RTCTrackEvent.prototype &&
              !("transceiver" in window.RTCTrackEvent.prototype)
            ) {
              Object.defineProperty(
                window.RTCTrackEvent.prototype,
                "transceiver",
                {
                  get: function get() {
                    return { receiver: this.receiver };
                  },
                }
              );
            }
          }

          function shimPeerConnection(window, browserDetails) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) !== "object" ||
              !(window.RTCPeerConnection || window.mozRTCPeerConnection)
            ) {
              return; // probably media.peerconnection.enabled=false in about:config
            }
            if (!window.RTCPeerConnection && window.mozRTCPeerConnection) {
              // very basic support for old versions.
              window.RTCPeerConnection = window.mozRTCPeerConnection;
            }

            if (browserDetails.version < 53) {
              // shim away need for obsolete RTCIceCandidate/RTCSessionDescription.
              [
                "setLocalDescription",
                "setRemoteDescription",
                "addIceCandidate",
              ].forEach(function (method) {
                var nativeMethod = window.RTCPeerConnection.prototype[method];
                var methodObj = _defineProperty({}, method, function () {
                  arguments[0] = new (
                    method === "addIceCandidate"
                      ? window.RTCIceCandidate
                      : window.RTCSessionDescription
                  )(arguments[0]);
                  return nativeMethod.apply(this, arguments);
                });
                window.RTCPeerConnection.prototype[method] = methodObj[method];
              });
            }

            var modernStatsTypes = {
              inboundrtp: "inbound-rtp",
              outboundrtp: "outbound-rtp",
              candidatepair: "candidate-pair",
              localcandidate: "local-candidate",
              remotecandidate: "remote-candidate",
            };

            var nativeGetStats = window.RTCPeerConnection.prototype.getStats;
            window.RTCPeerConnection.prototype.getStats = function getStats() {
              var _arguments = Array.prototype.slice.call(arguments),
                selector = _arguments[0],
                onSucc = _arguments[1],
                onErr = _arguments[2];

              return nativeGetStats
                .apply(this, [selector || null])
                .then(function (stats) {
                  if (browserDetails.version < 53 && !onSucc) {
                    // Shim only promise getStats with spec-hyphens in type names
                    // Leave callback version alone; misc old uses of forEach before Map
                    try {
                      stats.forEach(function (stat) {
                        stat.type = modernStatsTypes[stat.type] || stat.type;
                      });
                    } catch (e) {
                      if (e.name !== "TypeError") {
                        throw e;
                      }
                      // Avoid TypeError: "type" is read-only, in old versions. 34-43ish
                      stats.forEach(function (stat, i) {
                        stats.set(
                          i,
                          Object.assign({}, stat, {
                            type: modernStatsTypes[stat.type] || stat.type,
                          })
                        );
                      });
                    }
                  }
                  return stats;
                })
                .then(onSucc, onErr);
            };
          }

          function shimSenderGetStats(window) {
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" &&
                window.RTCPeerConnection &&
                window.RTCRtpSender
              )
            ) {
              return;
            }
            if (
              window.RTCRtpSender &&
              "getStats" in window.RTCRtpSender.prototype
            ) {
              return;
            }
            var origGetSenders = window.RTCPeerConnection.prototype.getSenders;
            if (origGetSenders) {
              window.RTCPeerConnection.prototype.getSenders =
                function getSenders() {
                  var _this = this;

                  var senders = origGetSenders.apply(this, []);
                  senders.forEach(function (sender) {
                    return (sender._pc = _this);
                  });
                  return senders;
                };
            }

            var origAddTrack = window.RTCPeerConnection.prototype.addTrack;
            if (origAddTrack) {
              window.RTCPeerConnection.prototype.addTrack =
                function addTrack() {
                  var sender = origAddTrack.apply(this, arguments);
                  sender._pc = this;
                  return sender;
                };
            }
            window.RTCRtpSender.prototype.getStats = function getStats() {
              return this.track
                ? this._pc.getStats(this.track)
                : Promise.resolve(new Map());
            };
          }

          function shimReceiverGetStats(window) {
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" &&
                window.RTCPeerConnection &&
                window.RTCRtpSender
              )
            ) {
              return;
            }
            if (
              window.RTCRtpSender &&
              "getStats" in window.RTCRtpReceiver.prototype
            ) {
              return;
            }
            var origGetReceivers =
              window.RTCPeerConnection.prototype.getReceivers;
            if (origGetReceivers) {
              window.RTCPeerConnection.prototype.getReceivers =
                function getReceivers() {
                  var _this2 = this;

                  var receivers = origGetReceivers.apply(this, []);
                  receivers.forEach(function (receiver) {
                    return (receiver._pc = _this2);
                  });
                  return receivers;
                };
            }
            utils.wrapPeerConnectionEvent(window, "track", function (e) {
              e.receiver._pc = e.srcElement;
              return e;
            });
            window.RTCRtpReceiver.prototype.getStats = function getStats() {
              return this._pc.getStats(this.track);
            };
          }

          function shimRemoveStream(window) {
            if (
              !window.RTCPeerConnection ||
              "removeStream" in window.RTCPeerConnection.prototype
            ) {
              return;
            }
            window.RTCPeerConnection.prototype.removeStream =
              function removeStream(stream) {
                var _this3 = this;

                utils.deprecated("removeStream", "removeTrack");
                this.getSenders().forEach(function (sender) {
                  if (
                    sender.track &&
                    stream.getTracks().includes(sender.track)
                  ) {
                    _this3.removeTrack(sender);
                  }
                });
              };
          }

          function shimRTCDataChannel(window) {
            // rename DataChannel to RTCDataChannel (native fix in FF60):
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1173851
            if (window.DataChannel && !window.RTCDataChannel) {
              window.RTCDataChannel = window.DataChannel;
            }
          }

          function shimAddTransceiver(window) {
            // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
            // Firefox ignores the init sendEncodings options passed to addTransceiver
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" && window.RTCPeerConnection
              )
            ) {
              return;
            }
            var origAddTransceiver =
              window.RTCPeerConnection.prototype.addTransceiver;
            if (origAddTransceiver) {
              window.RTCPeerConnection.prototype.addTransceiver =
                function addTransceiver() {
                  this.setParametersPromises = [];
                  var initParameters = arguments[1];
                  var shouldPerformCheck =
                    initParameters && "sendEncodings" in initParameters;
                  if (shouldPerformCheck) {
                    // If sendEncodings params are provided, validate grammar
                    initParameters.sendEncodings.forEach(function (
                      encodingParam
                    ) {
                      if ("rid" in encodingParam) {
                        var ridRegex = /^[a-z0-9]{0,16}$/i;
                        if (!ridRegex.test(encodingParam.rid)) {
                          throw new TypeError("Invalid RID value provided.");
                        }
                      }
                      if ("scaleResolutionDownBy" in encodingParam) {
                        if (
                          !(
                            parseFloat(encodingParam.scaleResolutionDownBy) >=
                            1.0
                          )
                        ) {
                          throw new RangeError(
                            "scale_resolution_down_by must be >= 1.0"
                          );
                        }
                      }
                      if ("maxFramerate" in encodingParam) {
                        if (!(parseFloat(encodingParam.maxFramerate) >= 0)) {
                          throw new RangeError("max_framerate must be >= 0.0");
                        }
                      }
                    });
                  }
                  var transceiver = origAddTransceiver.apply(this, arguments);
                  if (shouldPerformCheck) {
                    // Check if the init options were applied. If not we do this in an
                    // asynchronous way and save the promise reference in a global object.
                    // This is an ugly hack, but at the same time is way more robust than
                    // checking the sender parameters before and after the createOffer
                    // Also note that after the createoffer we are not 100% sure that
                    // the params were asynchronously applied so we might miss the
                    // opportunity to recreate offer.
                    var sender = transceiver.sender;

                    var params = sender.getParameters();
                    if (
                      !("encodings" in params) ||
                      // Avoid being fooled by patched getParameters() below.
                      (params.encodings.length === 1 &&
                        Object.keys(params.encodings[0]).length === 0)
                    ) {
                      params.encodings = initParameters.sendEncodings;
                      sender.sendEncodings = initParameters.sendEncodings;
                      this.setParametersPromises.push(
                        sender
                          .setParameters(params)
                          .then(function () {
                            delete sender.sendEncodings;
                          })
                          .catch(function () {
                            delete sender.sendEncodings;
                          })
                      );
                    }
                  }
                  return transceiver;
                };
            }
          }

          function shimGetParameters(window) {
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" && window.RTCRtpSender
              )
            ) {
              return;
            }
            var origGetParameters = window.RTCRtpSender.prototype.getParameters;
            if (origGetParameters) {
              window.RTCRtpSender.prototype.getParameters =
                function getParameters() {
                  var params = origGetParameters.apply(this, arguments);
                  if (!("encodings" in params)) {
                    params.encodings = [].concat(this.sendEncodings || [{}]);
                  }
                  return params;
                };
            }
          }

          function shimCreateOffer(window) {
            // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
            // Firefox ignores the init sendEncodings options passed to addTransceiver
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" && window.RTCPeerConnection
              )
            ) {
              return;
            }
            var origCreateOffer =
              window.RTCPeerConnection.prototype.createOffer;
            window.RTCPeerConnection.prototype.createOffer =
              function createOffer() {
                var _this4 = this,
                  _arguments2 = arguments;

                if (
                  this.setParametersPromises &&
                  this.setParametersPromises.length
                ) {
                  return Promise.all(this.setParametersPromises)
                    .then(function () {
                      return origCreateOffer.apply(_this4, _arguments2);
                    })
                    .finally(function () {
                      _this4.setParametersPromises = [];
                    });
                }
                return origCreateOffer.apply(this, arguments);
              };
          }

          function shimCreateAnswer(window) {
            // https://github.com/webrtcHacks/adapter/issues/998#issuecomment-516921647
            // Firefox ignores the init sendEncodings options passed to addTransceiver
            // https://bugzilla.mozilla.org/show_bug.cgi?id=1396918
            if (
              !(
                (typeof window === "undefined"
                  ? "undefined"
                  : _typeof(window)) === "object" && window.RTCPeerConnection
              )
            ) {
              return;
            }
            var origCreateAnswer =
              window.RTCPeerConnection.prototype.createAnswer;
            window.RTCPeerConnection.prototype.createAnswer =
              function createAnswer() {
                var _this5 = this,
                  _arguments3 = arguments;

                if (
                  this.setParametersPromises &&
                  this.setParametersPromises.length
                ) {
                  return Promise.all(this.setParametersPromises)
                    .then(function () {
                      return origCreateAnswer.apply(_this5, _arguments3);
                    })
                    .finally(function () {
                      _this5.setParametersPromises = [];
                    });
                }
                return origCreateAnswer.apply(this, arguments);
              };
          }
        },
        { "../utils": 11, "./getdisplaymedia": 8, "./getusermedia": 9 },
      ],
      8: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2018 The adapter.js project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });
          exports.shimGetDisplayMedia = shimGetDisplayMedia;
          function shimGetDisplayMedia(window, preferredMediaSource) {
            if (
              window.navigator.mediaDevices &&
              "getDisplayMedia" in window.navigator.mediaDevices
            ) {
              return;
            }
            if (!window.navigator.mediaDevices) {
              return;
            }
            window.navigator.mediaDevices.getDisplayMedia =
              function getDisplayMedia(constraints) {
                if (!(constraints && constraints.video)) {
                  var err = new DOMException(
                    "getDisplayMedia without video " +
                      "constraints is undefined"
                  );
                  err.name = "NotFoundError";
                  // from https://heycam.github.io/webidl/#idl-DOMException-error-names
                  err.code = 8;
                  return Promise.reject(err);
                }
                if (constraints.video === true) {
                  constraints.video = { mediaSource: preferredMediaSource };
                } else {
                  constraints.video.mediaSource = preferredMediaSource;
                }
                return window.navigator.mediaDevices.getUserMedia(constraints);
              };
          }
        },
        {},
      ],
      9: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          exports.shimGetUserMedia = shimGetUserMedia;

          var _utils = require("../utils");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          function shimGetUserMedia(window, browserDetails) {
            var navigator = window && window.navigator;
            var MediaStreamTrack = window && window.MediaStreamTrack;

            navigator.getUserMedia = function (
              constraints,
              onSuccess,
              onError
            ) {
              // Replace Firefox 44+'s deprecation warning with unprefixed version.
              utils.deprecated(
                "navigator.getUserMedia",
                "navigator.mediaDevices.getUserMedia"
              );
              navigator.mediaDevices
                .getUserMedia(constraints)
                .then(onSuccess, onError);
            };

            if (
              !(
                browserDetails.version > 55 &&
                "autoGainControl" in
                  navigator.mediaDevices.getSupportedConstraints()
              )
            ) {
              var remap = function remap(obj, a, b) {
                if (a in obj && !(b in obj)) {
                  obj[b] = obj[a];
                  delete obj[a];
                }
              };

              var nativeGetUserMedia = navigator.mediaDevices.getUserMedia.bind(
                navigator.mediaDevices
              );
              navigator.mediaDevices.getUserMedia = function (c) {
                if (
                  (typeof c === "undefined" ? "undefined" : _typeof(c)) ===
                    "object" &&
                  _typeof(c.audio) === "object"
                ) {
                  c = JSON.parse(JSON.stringify(c));
                  remap(c.audio, "autoGainControl", "mozAutoGainControl");
                  remap(c.audio, "noiseSuppression", "mozNoiseSuppression");
                }
                return nativeGetUserMedia(c);
              };

              if (MediaStreamTrack && MediaStreamTrack.prototype.getSettings) {
                var nativeGetSettings = MediaStreamTrack.prototype.getSettings;
                MediaStreamTrack.prototype.getSettings = function () {
                  var obj = nativeGetSettings.apply(this, arguments);
                  remap(obj, "mozAutoGainControl", "autoGainControl");
                  remap(obj, "mozNoiseSuppression", "noiseSuppression");
                  return obj;
                };
              }

              if (
                MediaStreamTrack &&
                MediaStreamTrack.prototype.applyConstraints
              ) {
                var nativeApplyConstraints =
                  MediaStreamTrack.prototype.applyConstraints;
                MediaStreamTrack.prototype.applyConstraints = function (c) {
                  if (
                    this.kind === "audio" &&
                    (typeof c === "undefined" ? "undefined" : _typeof(c)) ===
                      "object"
                  ) {
                    c = JSON.parse(JSON.stringify(c));
                    remap(c, "autoGainControl", "mozAutoGainControl");
                    remap(c, "noiseSuppression", "mozNoiseSuppression");
                  }
                  return nativeApplyConstraints.apply(this, [c]);
                };
              }
            }
          }
        },
        { "../utils": 11 },
      ],
      10: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          exports.shimLocalStreamsAPI = shimLocalStreamsAPI;
          exports.shimRemoteStreamsAPI = shimRemoteStreamsAPI;
          exports.shimCallbacksAPI = shimCallbacksAPI;
          exports.shimGetUserMedia = shimGetUserMedia;
          exports.shimConstraints = shimConstraints;
          exports.shimRTCIceServerUrls = shimRTCIceServerUrls;
          exports.shimTrackEventTransceiver = shimTrackEventTransceiver;
          exports.shimCreateOfferLegacy = shimCreateOfferLegacy;
          exports.shimAudioContext = shimAudioContext;

          var _utils = require("../utils");

          var utils = _interopRequireWildcard(_utils);

          function _interopRequireWildcard(obj) {
            if (obj && obj.__esModule) {
              return obj;
            } else {
              var newObj = {};
              if (obj != null) {
                for (var key in obj) {
                  if (Object.prototype.hasOwnProperty.call(obj, key))
                    newObj[key] = obj[key];
                }
              }
              newObj.default = obj;
              return newObj;
            }
          }

          function shimLocalStreamsAPI(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) !== "object" ||
              !window.RTCPeerConnection
            ) {
              return;
            }
            if (!("getLocalStreams" in window.RTCPeerConnection.prototype)) {
              window.RTCPeerConnection.prototype.getLocalStreams =
                function getLocalStreams() {
                  if (!this._localStreams) {
                    this._localStreams = [];
                  }
                  return this._localStreams;
                };
            }
            if (!("addStream" in window.RTCPeerConnection.prototype)) {
              var _addTrack = window.RTCPeerConnection.prototype.addTrack;
              window.RTCPeerConnection.prototype.addStream = function addStream(
                stream
              ) {
                var _this = this;

                if (!this._localStreams) {
                  this._localStreams = [];
                }
                if (!this._localStreams.includes(stream)) {
                  this._localStreams.push(stream);
                }
                // Try to emulate Chrome's behaviour of adding in audio-video order.
                // Safari orders by track id.
                stream.getAudioTracks().forEach(function (track) {
                  return _addTrack.call(_this, track, stream);
                });
                stream.getVideoTracks().forEach(function (track) {
                  return _addTrack.call(_this, track, stream);
                });
              };

              window.RTCPeerConnection.prototype.addTrack = function addTrack(
                track
              ) {
                var _this2 = this;

                for (
                  var _len = arguments.length,
                    streams = Array(_len > 1 ? _len - 1 : 0),
                    _key = 1;
                  _key < _len;
                  _key++
                ) {
                  streams[_key - 1] = arguments[_key];
                }

                if (streams) {
                  streams.forEach(function (stream) {
                    if (!_this2._localStreams) {
                      _this2._localStreams = [stream];
                    } else if (!_this2._localStreams.includes(stream)) {
                      _this2._localStreams.push(stream);
                    }
                  });
                }
                return _addTrack.apply(this, arguments);
              };
            }
            if (!("removeStream" in window.RTCPeerConnection.prototype)) {
              window.RTCPeerConnection.prototype.removeStream =
                function removeStream(stream) {
                  var _this3 = this;

                  if (!this._localStreams) {
                    this._localStreams = [];
                  }
                  var index = this._localStreams.indexOf(stream);
                  if (index === -1) {
                    return;
                  }
                  this._localStreams.splice(index, 1);
                  var tracks = stream.getTracks();
                  this.getSenders().forEach(function (sender) {
                    if (tracks.includes(sender.track)) {
                      _this3.removeTrack(sender);
                    }
                  });
                };
            }
          }

          function shimRemoteStreamsAPI(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) !== "object" ||
              !window.RTCPeerConnection
            ) {
              return;
            }
            if (!("getRemoteStreams" in window.RTCPeerConnection.prototype)) {
              window.RTCPeerConnection.prototype.getRemoteStreams =
                function getRemoteStreams() {
                  return this._remoteStreams ? this._remoteStreams : [];
                };
            }
            if (!("onaddstream" in window.RTCPeerConnection.prototype)) {
              Object.defineProperty(
                window.RTCPeerConnection.prototype,
                "onaddstream",
                {
                  get: function get() {
                    return this._onaddstream;
                  },
                  set: function set(f) {
                    var _this4 = this;

                    if (this._onaddstream) {
                      this.removeEventListener("addstream", this._onaddstream);
                      this.removeEventListener("track", this._onaddstreampoly);
                    }
                    this.addEventListener("addstream", (this._onaddstream = f));
                    this.addEventListener(
                      "track",
                      (this._onaddstreampoly = function (e) {
                        e.streams.forEach(function (stream) {
                          if (!_this4._remoteStreams) {
                            _this4._remoteStreams = [];
                          }
                          if (_this4._remoteStreams.includes(stream)) {
                            return;
                          }
                          _this4._remoteStreams.push(stream);
                          var event = new Event("addstream");
                          event.stream = stream;
                          _this4.dispatchEvent(event);
                        });
                      })
                    );
                  },
                }
              );
              var origSetRemoteDescription =
                window.RTCPeerConnection.prototype.setRemoteDescription;
              window.RTCPeerConnection.prototype.setRemoteDescription =
                function setRemoteDescription() {
                  var pc = this;
                  if (!this._onaddstreampoly) {
                    this.addEventListener(
                      "track",
                      (this._onaddstreampoly = function (e) {
                        e.streams.forEach(function (stream) {
                          if (!pc._remoteStreams) {
                            pc._remoteStreams = [];
                          }
                          if (pc._remoteStreams.indexOf(stream) >= 0) {
                            return;
                          }
                          pc._remoteStreams.push(stream);
                          var event = new Event("addstream");
                          event.stream = stream;
                          pc.dispatchEvent(event);
                        });
                      })
                    );
                  }
                  return origSetRemoteDescription.apply(pc, arguments);
                };
            }
          }

          function shimCallbacksAPI(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) !== "object" ||
              !window.RTCPeerConnection
            ) {
              return;
            }
            var prototype = window.RTCPeerConnection.prototype;
            var origCreateOffer = prototype.createOffer;
            var origCreateAnswer = prototype.createAnswer;
            var setLocalDescription = prototype.setLocalDescription;
            var setRemoteDescription = prototype.setRemoteDescription;
            var addIceCandidate = prototype.addIceCandidate;

            prototype.createOffer = function createOffer(
              successCallback,
              failureCallback
            ) {
              var options = arguments.length >= 2 ? arguments[2] : arguments[0];
              var promise = origCreateOffer.apply(this, [options]);
              if (!failureCallback) {
                return promise;
              }
              promise.then(successCallback, failureCallback);
              return Promise.resolve();
            };

            prototype.createAnswer = function createAnswer(
              successCallback,
              failureCallback
            ) {
              var options = arguments.length >= 2 ? arguments[2] : arguments[0];
              var promise = origCreateAnswer.apply(this, [options]);
              if (!failureCallback) {
                return promise;
              }
              promise.then(successCallback, failureCallback);
              return Promise.resolve();
            };

            var withCallback = function withCallback(
              description,
              successCallback,
              failureCallback
            ) {
              var promise = setLocalDescription.apply(this, [description]);
              if (!failureCallback) {
                return promise;
              }
              promise.then(successCallback, failureCallback);
              return Promise.resolve();
            };
            prototype.setLocalDescription = withCallback;

            withCallback = function withCallback(
              description,
              successCallback,
              failureCallback
            ) {
              var promise = setRemoteDescription.apply(this, [description]);
              if (!failureCallback) {
                return promise;
              }
              promise.then(successCallback, failureCallback);
              return Promise.resolve();
            };
            prototype.setRemoteDescription = withCallback;

            withCallback = function withCallback(
              candidate,
              successCallback,
              failureCallback
            ) {
              var promise = addIceCandidate.apply(this, [candidate]);
              if (!failureCallback) {
                return promise;
              }
              promise.then(successCallback, failureCallback);
              return Promise.resolve();
            };
            prototype.addIceCandidate = withCallback;
          }

          function shimGetUserMedia(window) {
            var navigator = window && window.navigator;

            if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
              // shim not needed in Safari 12.1
              var mediaDevices = navigator.mediaDevices;
              var _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
              navigator.mediaDevices.getUserMedia = function (constraints) {
                return _getUserMedia(shimConstraints(constraints));
              };
            }

            if (
              !navigator.getUserMedia &&
              navigator.mediaDevices &&
              navigator.mediaDevices.getUserMedia
            ) {
              navigator.getUserMedia = function getUserMedia(
                constraints,
                cb,
                errcb
              ) {
                navigator.mediaDevices
                  .getUserMedia(constraints)
                  .then(cb, errcb);
              }.bind(navigator);
            }
          }

          function shimConstraints(constraints) {
            if (constraints && constraints.video !== undefined) {
              return Object.assign({}, constraints, {
                video: utils.compactObject(constraints.video),
              });
            }

            return constraints;
          }

          function shimRTCIceServerUrls(window) {
            if (!window.RTCPeerConnection) {
              return;
            }
            // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
            var OrigPeerConnection = window.RTCPeerConnection;
            window.RTCPeerConnection = function RTCPeerConnection(
              pcConfig,
              pcConstraints
            ) {
              if (pcConfig && pcConfig.iceServers) {
                var newIceServers = [];
                for (var i = 0; i < pcConfig.iceServers.length; i++) {
                  var server = pcConfig.iceServers[i];
                  if (
                    !server.hasOwnProperty("urls") &&
                    server.hasOwnProperty("url")
                  ) {
                    utils.deprecated("RTCIceServer.url", "RTCIceServer.urls");
                    server = JSON.parse(JSON.stringify(server));
                    server.urls = server.url;
                    delete server.url;
                    newIceServers.push(server);
                  } else {
                    newIceServers.push(pcConfig.iceServers[i]);
                  }
                }
                pcConfig.iceServers = newIceServers;
              }
              return new OrigPeerConnection(pcConfig, pcConstraints);
            };
            window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
            // wrap static methods. Currently just generateCertificate.
            if ("generateCertificate" in OrigPeerConnection) {
              Object.defineProperty(
                window.RTCPeerConnection,
                "generateCertificate",
                {
                  get: function get() {
                    return OrigPeerConnection.generateCertificate;
                  },
                }
              );
            }
          }

          function shimTrackEventTransceiver(window) {
            // Add event.transceiver member over deprecated event.receiver
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object" &&
              window.RTCTrackEvent &&
              "receiver" in window.RTCTrackEvent.prototype &&
              !("transceiver" in window.RTCTrackEvent.prototype)
            ) {
              Object.defineProperty(
                window.RTCTrackEvent.prototype,
                "transceiver",
                {
                  get: function get() {
                    return { receiver: this.receiver };
                  },
                }
              );
            }
          }

          function shimCreateOfferLegacy(window) {
            var origCreateOffer =
              window.RTCPeerConnection.prototype.createOffer;
            window.RTCPeerConnection.prototype.createOffer =
              function createOffer(offerOptions) {
                if (offerOptions) {
                  if (typeof offerOptions.offerToReceiveAudio !== "undefined") {
                    // support bit values
                    offerOptions.offerToReceiveAudio =
                      !!offerOptions.offerToReceiveAudio;
                  }
                  var audioTransceiver = this.getTransceivers().find(function (
                    transceiver
                  ) {
                    return transceiver.receiver.track.kind === "audio";
                  });
                  if (
                    offerOptions.offerToReceiveAudio === false &&
                    audioTransceiver
                  ) {
                    if (audioTransceiver.direction === "sendrecv") {
                      if (audioTransceiver.setDirection) {
                        audioTransceiver.setDirection("sendonly");
                      } else {
                        audioTransceiver.direction = "sendonly";
                      }
                    } else if (audioTransceiver.direction === "recvonly") {
                      if (audioTransceiver.setDirection) {
                        audioTransceiver.setDirection("inactive");
                      } else {
                        audioTransceiver.direction = "inactive";
                      }
                    }
                  } else if (
                    offerOptions.offerToReceiveAudio === true &&
                    !audioTransceiver
                  ) {
                    this.addTransceiver("audio");
                  }

                  if (typeof offerOptions.offerToReceiveVideo !== "undefined") {
                    // support bit values
                    offerOptions.offerToReceiveVideo =
                      !!offerOptions.offerToReceiveVideo;
                  }
                  var videoTransceiver = this.getTransceivers().find(function (
                    transceiver
                  ) {
                    return transceiver.receiver.track.kind === "video";
                  });
                  if (
                    offerOptions.offerToReceiveVideo === false &&
                    videoTransceiver
                  ) {
                    if (videoTransceiver.direction === "sendrecv") {
                      if (videoTransceiver.setDirection) {
                        videoTransceiver.setDirection("sendonly");
                      } else {
                        videoTransceiver.direction = "sendonly";
                      }
                    } else if (videoTransceiver.direction === "recvonly") {
                      if (videoTransceiver.setDirection) {
                        videoTransceiver.setDirection("inactive");
                      } else {
                        videoTransceiver.direction = "inactive";
                      }
                    }
                  } else if (
                    offerOptions.offerToReceiveVideo === true &&
                    !videoTransceiver
                  ) {
                    this.addTransceiver("video");
                  }
                }
                return origCreateOffer.apply(this, arguments);
              };
          }

          function shimAudioContext(window) {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) !== "object" ||
              window.AudioContext
            ) {
              return;
            }
            window.AudioContext = window.webkitAudioContext;
          }
        },
        { "../utils": 11 },
      ],
      11: [
        function (require, module, exports) {
          /*
           *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
           *
           *  Use of this source code is governed by a BSD-style license
           *  that can be found in the LICENSE file in the root of the source
           *  tree.
           */
          /* eslint-env node */
          "use strict";

          Object.defineProperty(exports, "__esModule", {
            value: true,
          });

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          exports.extractVersion = extractVersion;
          exports.wrapPeerConnectionEvent = wrapPeerConnectionEvent;
          exports.disableLog = disableLog;
          exports.disableWarnings = disableWarnings;
          exports.log = log;
          exports.deprecated = deprecated;
          exports.detectBrowser = detectBrowser;
          exports.compactObject = compactObject;
          exports.walkStats = walkStats;
          exports.filterStats = filterStats;

          function _defineProperty(obj, key, value) {
            if (key in obj) {
              Object.defineProperty(obj, key, {
                value: value,
                enumerable: true,
                configurable: true,
                writable: true,
              });
            } else {
              obj[key] = value;
            }
            return obj;
          }

          var logDisabled_ = true;
          var deprecationWarnings_ = true;

          /**
           * Extract browser version out of the provided user agent string.
           *
           * @param {!string} uastring userAgent string.
           * @param {!string} expr Regular expression used as match criteria.
           * @param {!number} pos position in the version string to be returned.
           * @return {!number} browser version.
           */
          function extractVersion(uastring, expr, pos) {
            var match = uastring.match(expr);
            return match && match.length >= pos && parseInt(match[pos], 10);
          }

          // Wraps the peerconnection event eventNameToWrap in a function
          // which returns the modified event object (or false to prevent
          // the event).
          function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {
            if (!window.RTCPeerConnection) {
              return;
            }
            var proto = window.RTCPeerConnection.prototype;
            var nativeAddEventListener = proto.addEventListener;
            proto.addEventListener = function (nativeEventName, cb) {
              if (nativeEventName !== eventNameToWrap) {
                return nativeAddEventListener.apply(this, arguments);
              }
              var wrappedCallback = function wrappedCallback(e) {
                var modifiedEvent = wrapper(e);
                if (modifiedEvent) {
                  if (cb.handleEvent) {
                    cb.handleEvent(modifiedEvent);
                  } else {
                    cb(modifiedEvent);
                  }
                }
              };
              this._eventMap = this._eventMap || {};
              if (!this._eventMap[eventNameToWrap]) {
                this._eventMap[eventNameToWrap] = new Map();
              }
              this._eventMap[eventNameToWrap].set(cb, wrappedCallback);
              return nativeAddEventListener.apply(this, [
                nativeEventName,
                wrappedCallback,
              ]);
            };

            var nativeRemoveEventListener = proto.removeEventListener;
            proto.removeEventListener = function (nativeEventName, cb) {
              if (
                nativeEventName !== eventNameToWrap ||
                !this._eventMap ||
                !this._eventMap[eventNameToWrap]
              ) {
                return nativeRemoveEventListener.apply(this, arguments);
              }
              if (!this._eventMap[eventNameToWrap].has(cb)) {
                return nativeRemoveEventListener.apply(this, arguments);
              }
              var unwrappedCb = this._eventMap[eventNameToWrap].get(cb);
              this._eventMap[eventNameToWrap].delete(cb);
              if (this._eventMap[eventNameToWrap].size === 0) {
                delete this._eventMap[eventNameToWrap];
              }
              if (Object.keys(this._eventMap).length === 0) {
                delete this._eventMap;
              }
              return nativeRemoveEventListener.apply(this, [
                nativeEventName,
                unwrappedCb,
              ]);
            };

            Object.defineProperty(proto, "on" + eventNameToWrap, {
              get: function get() {
                return this["_on" + eventNameToWrap];
              },
              set: function set(cb) {
                if (this["_on" + eventNameToWrap]) {
                  this.removeEventListener(
                    eventNameToWrap,
                    this["_on" + eventNameToWrap]
                  );
                  delete this["_on" + eventNameToWrap];
                }
                if (cb) {
                  this.addEventListener(
                    eventNameToWrap,
                    (this["_on" + eventNameToWrap] = cb)
                  );
                }
              },

              enumerable: true,
              configurable: true,
            });
          }

          function disableLog(bool) {
            if (typeof bool !== "boolean") {
              return new Error(
                "Argument type: " +
                  (typeof bool === "undefined" ? "undefined" : _typeof(bool)) +
                  ". Please use a boolean."
              );
            }
            logDisabled_ = bool;
            return bool
              ? "adapter.js logging disabled"
              : "adapter.js logging enabled";
          }

          /**
           * Disable or enable deprecation warnings
           * @param {!boolean} bool set to true to disable warnings.
           */
          function disableWarnings(bool) {
            if (typeof bool !== "boolean") {
              return new Error(
                "Argument type: " +
                  (typeof bool === "undefined" ? "undefined" : _typeof(bool)) +
                  ". Please use a boolean."
              );
            }
            deprecationWarnings_ = !bool;
            return (
              "adapter.js deprecation warnings " +
              (bool ? "disabled" : "enabled")
            );
          }

          function log() {
            if (
              (typeof window === "undefined"
                ? "undefined"
                : _typeof(window)) === "object"
            ) {
              if (logDisabled_) {
                return;
              }
              if (
                typeof console !== "undefined" &&
                typeof console.log === "function"
              ) {
                console.log.apply(console, arguments);
              }
            }
          }

          /**
           * Shows a deprecation warning suggesting the modern and spec-compatible API.
           */
          function deprecated(oldMethod, newMethod) {
            if (!deprecationWarnings_) {
              return;
            }
            console.warn(
              oldMethod +
                " is deprecated, please use " +
                newMethod +
                " instead."
            );
          }

          /**
           * Browser detector.
           *
           * @return {object} result containing browser and version
           *     properties.
           */
          function detectBrowser(window) {
            // Returned result object.
            var result = { browser: null, version: null };

            // Fail early if it's not a browser
            if (typeof window === "undefined" || !window.navigator) {
              result.browser = "Not a browser.";
              return result;
            }

            var navigator = window.navigator;

            if (navigator.mozGetUserMedia) {
              // Firefox.
              result.browser = "firefox";
              result.version = extractVersion(
                navigator.userAgent,
                /Firefox\/(\d+)\./,
                1
              );
            } else if (
              navigator.webkitGetUserMedia ||
              (window.isSecureContext === false &&
                window.webkitRTCPeerConnection &&
                !window.RTCIceGatherer)
            ) {
              // Chrome, Chromium, Webview, Opera.
              // Version matches Chrome/WebRTC version.
              // Chrome 74 removed webkitGetUserMedia on http as well so we need the
              // more complicated fallback to webkitRTCPeerConnection.
              result.browser = "chrome";
              result.version = extractVersion(
                navigator.userAgent,
                /Chrom(e|ium)\/(\d+)\./,
                2
              );
            } else if (
              window.RTCPeerConnection &&
              navigator.userAgent.match(/AppleWebKit\/(\d+)\./)
            ) {
              // Safari.
              result.browser = "safari";
              result.version = extractVersion(
                navigator.userAgent,
                /AppleWebKit\/(\d+)\./,
                1
              );
              result.supportsUnifiedPlan =
                window.RTCRtpTransceiver &&
                "currentDirection" in window.RTCRtpTransceiver.prototype;
            } else {
              // Default fallthrough: not supported.
              result.browser = "Not a supported browser.";
              return result;
            }

            return result;
          }

          /**
           * Checks if something is an object.
           *
           * @param {*} val The something you want to check.
           * @return true if val is an object, false otherwise.
           */
          function isObject(val) {
            return Object.prototype.toString.call(val) === "[object Object]";
          }

          /**
           * Remove all empty objects and undefined values
           * from a nested object -- an enhanced and vanilla version
           * of Lodash's `compact`.
           */
          function compactObject(data) {
            if (!isObject(data)) {
              return data;
            }

            return Object.keys(data).reduce(function (accumulator, key) {
              var isObj = isObject(data[key]);
              var value = isObj ? compactObject(data[key]) : data[key];
              var isEmptyObject = isObj && !Object.keys(value).length;
              if (value === undefined || isEmptyObject) {
                return accumulator;
              }
              return Object.assign(
                accumulator,
                _defineProperty({}, key, value)
              );
            }, {});
          }

          /* iterates the stats graph recursively. */
          function walkStats(stats, base, resultSet) {
            if (!base || resultSet.has(base.id)) {
              return;
            }
            resultSet.set(base.id, base);
            Object.keys(base).forEach(function (name) {
              if (name.endsWith("Id")) {
                walkStats(stats, stats.get(base[name]), resultSet);
              } else if (name.endsWith("Ids")) {
                base[name].forEach(function (id) {
                  walkStats(stats, stats.get(id), resultSet);
                });
              }
            });
          }

          /* filter getStats for a sender/receiver track. */
          function filterStats(result, track, outbound) {
            var streamStatsType = outbound ? "outbound-rtp" : "inbound-rtp";
            var filteredResult = new Map();
            if (track === null) {
              return filteredResult;
            }
            var trackStats = [];
            result.forEach(function (value) {
              if (
                value.type === "track" &&
                value.trackIdentifier === track.id
              ) {
                trackStats.push(value);
              }
            });
            trackStats.forEach(function (trackStat) {
              result.forEach(function (stats) {
                if (
                  stats.type === streamStatsType &&
                  stats.trackId === trackStat.id
                ) {
                  walkStats(result, stats, filteredResult);
                }
              });
            });
            return filteredResult;
          }
        },
        {},
      ],
      12: [
        function (require, module, exports) {
          /* eslint-env node */
          "use strict";

          // SDP helpers.

          var _typeof =
            typeof Symbol === "function" && typeof Symbol.iterator === "symbol"
              ? function (obj) {
                  return typeof obj;
                }
              : function (obj) {
                  return obj &&
                    typeof Symbol === "function" &&
                    obj.constructor === Symbol &&
                    obj !== Symbol.prototype
                    ? "symbol"
                    : typeof obj;
                };

          var SDPUtils = {};

          // Generate an alphanumeric identifier for cname or mids.
          // TODO: use UUIDs instead? https://gist.github.com/jed/982883
          SDPUtils.generateIdentifier = function () {
            return Math.random().toString(36).substr(2, 10);
          };

          // The RTCP CNAME used by all peerconnections from the same JS.
          SDPUtils.localCName = SDPUtils.generateIdentifier();

          // Splits SDP into lines, dealing with both CRLF and LF.
          SDPUtils.splitLines = function (blob) {
            return blob
              .trim()
              .split("\n")
              .map(function (line) {
                return line.trim();
              });
          };
          // Splits SDP into sessionpart and mediasections. Ensures CRLF.
          SDPUtils.splitSections = function (blob) {
            var parts = blob.split("\nm=");
            return parts.map(function (part, index) {
              return (index > 0 ? "m=" + part : part).trim() + "\r\n";
            });
          };

          // Returns the session description.
          SDPUtils.getDescription = function (blob) {
            var sections = SDPUtils.splitSections(blob);
            return sections && sections[0];
          };

          // Returns the individual media sections.
          SDPUtils.getMediaSections = function (blob) {
            var sections = SDPUtils.splitSections(blob);
            sections.shift();
            return sections;
          };

          // Returns lines that start with a certain prefix.
          SDPUtils.matchPrefix = function (blob, prefix) {
            return SDPUtils.splitLines(blob).filter(function (line) {
              return line.indexOf(prefix) === 0;
            });
          };

          // Parses an ICE candidate line. Sample input:
          // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
          // rport 55996"
          // Input can be prefixed with a=.
          SDPUtils.parseCandidate = function (line) {
            var parts = void 0;
            // Parse both variants.
            if (line.indexOf("a=candidate:") === 0) {
              parts = line.substring(12).split(" ");
            } else {
              parts = line.substring(10).split(" ");
            }

            var candidate = {
              foundation: parts[0],
              component: { 1: "rtp", 2: "rtcp" }[parts[1]] || parts[1],
              protocol: parts[2].toLowerCase(),
              priority: parseInt(parts[3], 10),
              ip: parts[4],
              address: parts[4], // address is an alias for ip.
              port: parseInt(parts[5], 10),
              // skip parts[6] == 'typ'
              type: parts[7],
            };

            for (var i = 8; i < parts.length; i += 2) {
              switch (parts[i]) {
                case "raddr":
                  candidate.relatedAddress = parts[i + 1];
                  break;
                case "rport":
                  candidate.relatedPort = parseInt(parts[i + 1], 10);
                  break;
                case "tcptype":
                  candidate.tcpType = parts[i + 1];
                  break;
                case "ufrag":
                  candidate.ufrag = parts[i + 1]; // for backward compatibility.
                  candidate.usernameFragment = parts[i + 1];
                  break;
                default:
                  // extension handling, in particular ufrag. Don't overwrite.
                  if (candidate[parts[i]] === undefined) {
                    candidate[parts[i]] = parts[i + 1];
                  }
                  break;
              }
            }
            return candidate;
          };

          // Translates a candidate object into SDP candidate attribute.
          // This does not include the a= prefix!
          SDPUtils.writeCandidate = function (candidate) {
            var sdp = [];
            sdp.push(candidate.foundation);

            var component = candidate.component;
            if (component === "rtp") {
              sdp.push(1);
            } else if (component === "rtcp") {
              sdp.push(2);
            } else {
              sdp.push(component);
            }
            sdp.push(candidate.protocol.toUpperCase());
            sdp.push(candidate.priority);
            sdp.push(candidate.address || candidate.ip);
            sdp.push(candidate.port);

            var type = candidate.type;
            sdp.push("typ");
            sdp.push(type);
            if (
              type !== "host" &&
              candidate.relatedAddress &&
              candidate.relatedPort
            ) {
              sdp.push("raddr");
              sdp.push(candidate.relatedAddress);
              sdp.push("rport");
              sdp.push(candidate.relatedPort);
            }
            if (
              candidate.tcpType &&
              candidate.protocol.toLowerCase() === "tcp"
            ) {
              sdp.push("tcptype");
              sdp.push(candidate.tcpType);
            }
            if (candidate.usernameFragment || candidate.ufrag) {
              sdp.push("ufrag");
              sdp.push(candidate.usernameFragment || candidate.ufrag);
            }
            return "candidate:" + sdp.join(" ");
          };

          // Parses an ice-options line, returns an array of option tags.
          // Sample input:
          // a=ice-options:foo bar
          SDPUtils.parseIceOptions = function (line) {
            return line.substr(14).split(" ");
          };

          // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
          // a=rtpmap:111 opus/48000/2
          SDPUtils.parseRtpMap = function (line) {
            var parts = line.substr(9).split(" ");
            var parsed = {
              payloadType: parseInt(parts.shift(), 10), // was: id
            };

            parts = parts[0].split("/");

            parsed.name = parts[0];
            parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
            parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
            // legacy alias, got renamed back to channels in ORTC.
            parsed.numChannels = parsed.channels;
            return parsed;
          };

          // Generates a rtpmap line from RTCRtpCodecCapability or
          // RTCRtpCodecParameters.
          SDPUtils.writeRtpMap = function (codec) {
            var pt = codec.payloadType;
            if (codec.preferredPayloadType !== undefined) {
              pt = codec.preferredPayloadType;
            }
            var channels = codec.channels || codec.numChannels || 1;
            return (
              "a=rtpmap:" +
              pt +
              " " +
              codec.name +
              "/" +
              codec.clockRate +
              (channels !== 1 ? "/" + channels : "") +
              "\r\n"
            );
          };

          // Parses a extmap line (headerextension from RFC 5285). Sample input:
          // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
          // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
          SDPUtils.parseExtmap = function (line) {
            var parts = line.substr(9).split(" ");
            return {
              id: parseInt(parts[0], 10),
              direction:
                parts[0].indexOf("/") > 0 ? parts[0].split("/")[1] : "sendrecv",
              uri: parts[1],
            };
          };

          // Generates an extmap line from RTCRtpHeaderExtensionParameters or
          // RTCRtpHeaderExtension.
          SDPUtils.writeExtmap = function (headerExtension) {
            return (
              "a=extmap:" +
              (headerExtension.id || headerExtension.preferredId) +
              (headerExtension.direction &&
              headerExtension.direction !== "sendrecv"
                ? "/" + headerExtension.direction
                : "") +
              " " +
              headerExtension.uri +
              "\r\n"
            );
          };

          // Parses a fmtp line, returns dictionary. Sample input:
          // a=fmtp:96 vbr=on;cng=on
          // Also deals with vbr=on; cng=on
          SDPUtils.parseFmtp = function (line) {
            var parsed = {};
            var kv = void 0;
            var parts = line.substr(line.indexOf(" ") + 1).split(";");
            for (var j = 0; j < parts.length; j++) {
              kv = parts[j].trim().split("=");
              parsed[kv[0].trim()] = kv[1];
            }
            return parsed;
          };

          // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
          SDPUtils.writeFmtp = function (codec) {
            var line = "";
            var pt = codec.payloadType;
            if (codec.preferredPayloadType !== undefined) {
              pt = codec.preferredPayloadType;
            }
            if (codec.parameters && Object.keys(codec.parameters).length) {
              var params = [];
              Object.keys(codec.parameters).forEach(function (param) {
                if (codec.parameters[param] !== undefined) {
                  params.push(param + "=" + codec.parameters[param]);
                } else {
                  params.push(param);
                }
              });
              line += "a=fmtp:" + pt + " " + params.join(";") + "\r\n";
            }
            return line;
          };

          // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
          // a=rtcp-fb:98 nack rpsi
          SDPUtils.parseRtcpFb = function (line) {
            var parts = line.substr(line.indexOf(" ") + 1).split(" ");
            return {
              type: parts.shift(),
              parameter: parts.join(" "),
            };
          };

          // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
          SDPUtils.writeRtcpFb = function (codec) {
            var lines = "";
            var pt = codec.payloadType;
            if (codec.preferredPayloadType !== undefined) {
              pt = codec.preferredPayloadType;
            }
            if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
              // FIXME: special handling for trr-int?
              codec.rtcpFeedback.forEach(function (fb) {
                lines +=
                  "a=rtcp-fb:" +
                  pt +
                  " " +
                  fb.type +
                  (fb.parameter && fb.parameter.length
                    ? " " + fb.parameter
                    : "") +
                  "\r\n";
              });
            }
            return lines;
          };

          // Parses a RFC 5576 ssrc media attribute. Sample input:
          // a=ssrc:3735928559 cname:something
          SDPUtils.parseSsrcMedia = function (line) {
            var sp = line.indexOf(" ");
            var parts = {
              ssrc: parseInt(line.substr(7, sp - 7), 10),
            };
            var colon = line.indexOf(":", sp);
            if (colon > -1) {
              parts.attribute = line.substr(sp + 1, colon - sp - 1);
              parts.value = line.substr(colon + 1);
            } else {
              parts.attribute = line.substr(sp + 1);
            }
            return parts;
          };

          // Parse a ssrc-group line (see RFC 5576). Sample input:
          // a=ssrc-group:semantics 12 34
          SDPUtils.parseSsrcGroup = function (line) {
            var parts = line.substr(13).split(" ");
            return {
              semantics: parts.shift(),
              ssrcs: parts.map(function (ssrc) {
                return parseInt(ssrc, 10);
              }),
            };
          };

          // Extracts the MID (RFC 5888) from a media section.
          // Returns the MID or undefined if no mid line was found.
          SDPUtils.getMid = function (mediaSection) {
            var mid = SDPUtils.matchPrefix(mediaSection, "a=mid:")[0];
            if (mid) {
              return mid.substr(6);
            }
          };

          // Parses a fingerprint line for DTLS-SRTP.
          SDPUtils.parseFingerprint = function (line) {
            var parts = line.substr(14).split(" ");
            return {
              algorithm: parts[0].toLowerCase(), // algorithm is case-sensitive in Edge.
              value: parts[1].toUpperCase(), // the definition is upper-case in RFC 4572.
            };
          };

          // Extracts DTLS parameters from SDP media section or sessionpart.
          // FIXME: for consistency with other functions this should only
          //   get the fingerprint line as input. See also getIceParameters.
          SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
            var lines = SDPUtils.matchPrefix(
              mediaSection + sessionpart,
              "a=fingerprint:"
            );
            // Note: a=setup line is ignored since we use the 'auto' role in Edge.
            return {
              role: "auto",
              fingerprints: lines.map(SDPUtils.parseFingerprint),
            };
          };

          // Serializes DTLS parameters to SDP.
          SDPUtils.writeDtlsParameters = function (params, setupType) {
            var sdp = "a=setup:" + setupType + "\r\n";
            params.fingerprints.forEach(function (fp) {
              sdp += "a=fingerprint:" + fp.algorithm + " " + fp.value + "\r\n";
            });
            return sdp;
          };

          // Parses a=crypto lines into
          //   https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
          SDPUtils.parseCryptoLine = function (line) {
            var parts = line.substr(9).split(" ");
            return {
              tag: parseInt(parts[0], 10),
              cryptoSuite: parts[1],
              keyParams: parts[2],
              sessionParams: parts.slice(3),
            };
          };

          SDPUtils.writeCryptoLine = function (parameters) {
            return (
              "a=crypto:" +
              parameters.tag +
              " " +
              parameters.cryptoSuite +
              " " +
              (_typeof(parameters.keyParams) === "object"
                ? SDPUtils.writeCryptoKeyParams(parameters.keyParams)
                : parameters.keyParams) +
              (parameters.sessionParams
                ? " " + parameters.sessionParams.join(" ")
                : "") +
              "\r\n"
            );
          };

          // Parses the crypto key parameters into
          //   https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
          SDPUtils.parseCryptoKeyParams = function (keyParams) {
            if (keyParams.indexOf("inline:") !== 0) {
              return null;
            }
            var parts = keyParams.substr(7).split("|");
            return {
              keyMethod: "inline",
              keySalt: parts[0],
              lifeTime: parts[1],
              mkiValue: parts[2] ? parts[2].split(":")[0] : undefined,
              mkiLength: parts[2] ? parts[2].split(":")[1] : undefined,
            };
          };

          SDPUtils.writeCryptoKeyParams = function (keyParams) {
            return (
              keyParams.keyMethod +
              ":" +
              keyParams.keySalt +
              (keyParams.lifeTime ? "|" + keyParams.lifeTime : "") +
              (keyParams.mkiValue && keyParams.mkiLength
                ? "|" + keyParams.mkiValue + ":" + keyParams.mkiLength
                : "")
            );
          };

          // Extracts all SDES parameters.
          SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
            var lines = SDPUtils.matchPrefix(
              mediaSection + sessionpart,
              "a=crypto:"
            );
            return lines.map(SDPUtils.parseCryptoLine);
          };

          // Parses ICE information from SDP media section or sessionpart.
          // FIXME: for consistency with other functions this should only
          //   get the ice-ufrag and ice-pwd lines as input.
          SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
            var ufrag = SDPUtils.matchPrefix(
              mediaSection + sessionpart,
              "a=ice-ufrag:"
            )[0];
            var pwd = SDPUtils.matchPrefix(
              mediaSection + sessionpart,
              "a=ice-pwd:"
            )[0];
            if (!(ufrag && pwd)) {
              return null;
            }
            return {
              usernameFragment: ufrag.substr(12),
              password: pwd.substr(10),
            };
          };

          // Serializes ICE parameters to SDP.
          SDPUtils.writeIceParameters = function (params) {
            var sdp =
              "a=ice-ufrag:" +
              params.usernameFragment +
              "\r\n" +
              "a=ice-pwd:" +
              params.password +
              "\r\n";
            if (params.iceLite) {
              sdp += "a=ice-lite\r\n";
            }
            return sdp;
          };

          // Parses the SDP media section and returns RTCRtpParameters.
          SDPUtils.parseRtpParameters = function (mediaSection) {
            var description = {
              codecs: [],
              headerExtensions: [],
              fecMechanisms: [],
              rtcp: [],
            };
            var lines = SDPUtils.splitLines(mediaSection);
            var mline = lines[0].split(" ");
            for (var i = 3; i < mline.length; i++) {
              // find all codecs from mline[3..]
              var pt = mline[i];
              var rtpmapline = SDPUtils.matchPrefix(
                mediaSection,
                "a=rtpmap:" + pt + " "
              )[0];
              if (rtpmapline) {
                var codec = SDPUtils.parseRtpMap(rtpmapline);
                var fmtps = SDPUtils.matchPrefix(
                  mediaSection,
                  "a=fmtp:" + pt + " "
                );
                // Only the first a=fmtp:<pt> is considered.
                codec.parameters = fmtps.length
                  ? SDPUtils.parseFmtp(fmtps[0])
                  : {};
                codec.rtcpFeedback = SDPUtils.matchPrefix(
                  mediaSection,
                  "a=rtcp-fb:" + pt + " "
                ).map(SDPUtils.parseRtcpFb);
                description.codecs.push(codec);
                // parse FEC mechanisms from rtpmap lines.
                switch (codec.name.toUpperCase()) {
                  case "RED":
                  case "ULPFEC":
                    description.fecMechanisms.push(codec.name.toUpperCase());
                    break;
                  default:
                    // only RED and ULPFEC are recognized as FEC mechanisms.
                    break;
                }
              }
            }
            SDPUtils.matchPrefix(mediaSection, "a=extmap:").forEach(function (
              line
            ) {
              description.headerExtensions.push(SDPUtils.parseExtmap(line));
            });
            // FIXME: parse rtcp.
            return description;
          };

          // Generates parts of the SDP media section describing the capabilities /
          // parameters.
          SDPUtils.writeRtpDescription = function (kind, caps) {
            var sdp = "";

            // Build the mline.
            sdp += "m=" + kind + " ";
            sdp += caps.codecs.length > 0 ? "9" : "0"; // reject if no codecs.
            sdp += " UDP/TLS/RTP/SAVPF ";
            sdp +=
              caps.codecs
                .map(function (codec) {
                  if (codec.preferredPayloadType !== undefined) {
                    return codec.preferredPayloadType;
                  }
                  return codec.payloadType;
                })
                .join(" ") + "\r\n";

            sdp += "c=IN IP4 0.0.0.0\r\n";
            sdp += "a=rtcp:9 IN IP4 0.0.0.0\r\n";

            // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
            caps.codecs.forEach(function (codec) {
              sdp += SDPUtils.writeRtpMap(codec);
              sdp += SDPUtils.writeFmtp(codec);
              sdp += SDPUtils.writeRtcpFb(codec);
            });
            var maxptime = 0;
            caps.codecs.forEach(function (codec) {
              if (codec.maxptime > maxptime) {
                maxptime = codec.maxptime;
              }
            });
            if (maxptime > 0) {
              sdp += "a=maxptime:" + maxptime + "\r\n";
            }

            if (caps.headerExtensions) {
              caps.headerExtensions.forEach(function (extension) {
                sdp += SDPUtils.writeExtmap(extension);
              });
            }
            // FIXME: write fecMechanisms.
            return sdp;
          };

          // Parses the SDP media section and returns an array of
          // RTCRtpEncodingParameters.
          SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
            var encodingParameters = [];
            var description = SDPUtils.parseRtpParameters(mediaSection);
            var hasRed = description.fecMechanisms.indexOf("RED") !== -1;
            var hasUlpfec = description.fecMechanisms.indexOf("ULPFEC") !== -1;

            // filter a=ssrc:... cname:, ignore PlanB-msid
            var ssrcs = SDPUtils.matchPrefix(mediaSection, "a=ssrc:")
              .map(function (line) {
                return SDPUtils.parseSsrcMedia(line);
              })
              .filter(function (parts) {
                return parts.attribute === "cname";
              });
            var primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
            var secondarySsrc = void 0;

            var flows = SDPUtils.matchPrefix(
              mediaSection,
              "a=ssrc-group:FID"
            ).map(function (line) {
              var parts = line.substr(17).split(" ");
              return parts.map(function (part) {
                return parseInt(part, 10);
              });
            });
            if (
              flows.length > 0 &&
              flows[0].length > 1 &&
              flows[0][0] === primarySsrc
            ) {
              secondarySsrc = flows[0][1];
            }

            description.codecs.forEach(function (codec) {
              if (codec.name.toUpperCase() === "RTX" && codec.parameters.apt) {
                var encParam = {
                  ssrc: primarySsrc,
                  codecPayloadType: parseInt(codec.parameters.apt, 10),
                };
                if (primarySsrc && secondarySsrc) {
                  encParam.rtx = { ssrc: secondarySsrc };
                }
                encodingParameters.push(encParam);
                if (hasRed) {
                  encParam = JSON.parse(JSON.stringify(encParam));
                  encParam.fec = {
                    ssrc: primarySsrc,
                    mechanism: hasUlpfec ? "red+ulpfec" : "red",
                  };
                  encodingParameters.push(encParam);
                }
              }
            });
            if (encodingParameters.length === 0 && primarySsrc) {
              encodingParameters.push({
                ssrc: primarySsrc,
              });
            }

            // we support both b=AS and b=TIAS but interpret AS as TIAS.
            var bandwidth = SDPUtils.matchPrefix(mediaSection, "b=");
            if (bandwidth.length) {
              if (bandwidth[0].indexOf("b=TIAS:") === 0) {
                bandwidth = parseInt(bandwidth[0].substr(7), 10);
              } else if (bandwidth[0].indexOf("b=AS:") === 0) {
                // use formula from JSEP to convert b=AS to TIAS value.
                bandwidth =
                  parseInt(bandwidth[0].substr(5), 10) * 1000 * 0.95 -
                  50 * 40 * 8;
              } else {
                bandwidth = undefined;
              }
              encodingParameters.forEach(function (params) {
                params.maxBitrate = bandwidth;
              });
            }
            return encodingParameters;
          };

          // parses http://draft.ortc.org/#rtcrtcpparameters*
          SDPUtils.parseRtcpParameters = function (mediaSection) {
            var rtcpParameters = {};

            // Gets the first SSRC. Note that with RTX there might be multiple
            // SSRCs.
            var remoteSsrc = SDPUtils.matchPrefix(mediaSection, "a=ssrc:")
              .map(function (line) {
                return SDPUtils.parseSsrcMedia(line);
              })
              .filter(function (obj) {
                return obj.attribute === "cname";
              })[0];
            if (remoteSsrc) {
              rtcpParameters.cname = remoteSsrc.value;
              rtcpParameters.ssrc = remoteSsrc.ssrc;
            }

            // Edge uses the compound attribute instead of reducedSize
            // compound is !reducedSize
            var rsize = SDPUtils.matchPrefix(mediaSection, "a=rtcp-rsize");
            rtcpParameters.reducedSize = rsize.length > 0;
            rtcpParameters.compound = rsize.length === 0;

            // parses the rtcp-mux attrіbute.
            // Note that Edge does not support unmuxed RTCP.
            var mux = SDPUtils.matchPrefix(mediaSection, "a=rtcp-mux");
            rtcpParameters.mux = mux.length > 0;

            return rtcpParameters;
          };

          SDPUtils.writeRtcpParameters = function (rtcpParameters) {
            var sdp = "";
            if (rtcpParameters.reducedSize) {
              sdp += "a=rtcp-rsize\r\n";
            }
            if (rtcpParameters.mux) {
              sdp += "a=rtcp-mux\r\n";
            }
            if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
              sdp +=
                "a=ssrc:" +
                rtcpParameters.ssrc +
                " cname:" +
                rtcpParameters.cname +
                "\r\n";
            }
            return sdp;
          };

          // parses either a=msid: or a=ssrc:... msid lines and returns
          // the id of the MediaStream and MediaStreamTrack.
          SDPUtils.parseMsid = function (mediaSection) {
            var parts = void 0;
            var spec = SDPUtils.matchPrefix(mediaSection, "a=msid:");
            if (spec.length === 1) {
              parts = spec[0].substr(7).split(" ");
              return { stream: parts[0], track: parts[1] };
            }
            var planB = SDPUtils.matchPrefix(mediaSection, "a=ssrc:")
              .map(function (line) {
                return SDPUtils.parseSsrcMedia(line);
              })
              .filter(function (msidParts) {
                return msidParts.attribute === "msid";
              });
            if (planB.length > 0) {
              parts = planB[0].value.split(" ");
              return { stream: parts[0], track: parts[1] };
            }
          };

          // SCTP
          // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
          // to draft-ietf-mmusic-sctp-sdp-05
          SDPUtils.parseSctpDescription = function (mediaSection) {
            var mline = SDPUtils.parseMLine(mediaSection);
            var maxSizeLine = SDPUtils.matchPrefix(
              mediaSection,
              "a=max-message-size:"
            );
            var maxMessageSize = void 0;
            if (maxSizeLine.length > 0) {
              maxMessageSize = parseInt(maxSizeLine[0].substr(19), 10);
            }
            if (isNaN(maxMessageSize)) {
              maxMessageSize = 65536;
            }
            var sctpPort = SDPUtils.matchPrefix(mediaSection, "a=sctp-port:");
            if (sctpPort.length > 0) {
              return {
                port: parseInt(sctpPort[0].substr(12), 10),
                protocol: mline.fmt,
                maxMessageSize: maxMessageSize,
              };
            }
            var sctpMapLines = SDPUtils.matchPrefix(mediaSection, "a=sctpmap:");
            if (sctpMapLines.length > 0) {
              var parts = sctpMapLines[0].substr(10).split(" ");
              return {
                port: parseInt(parts[0], 10),
                protocol: parts[1],
                maxMessageSize: maxMessageSize,
              };
            }
          };

          // SCTP
          // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
          // support by now receiving in this format, unless we originally parsed
          // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
          // protocol of DTLS/SCTP -- without UDP/ or TCP/)
          SDPUtils.writeSctpDescription = function (media, sctp) {
            var output = [];
            if (media.protocol !== "DTLS/SCTP") {
              output = [
                "m=" +
                  media.kind +
                  " 9 " +
                  media.protocol +
                  " " +
                  sctp.protocol +
                  "\r\n",
                "c=IN IP4 0.0.0.0\r\n",
                "a=sctp-port:" + sctp.port + "\r\n",
              ];
            } else {
              output = [
                "m=" +
                  media.kind +
                  " 9 " +
                  media.protocol +
                  " " +
                  sctp.port +
                  "\r\n",
                "c=IN IP4 0.0.0.0\r\n",
                "a=sctpmap:" + sctp.port + " " + sctp.protocol + " 65535\r\n",
              ];
            }
            if (sctp.maxMessageSize !== undefined) {
              output.push("a=max-message-size:" + sctp.maxMessageSize + "\r\n");
            }
            return output.join("");
          };

          // Generate a session ID for SDP.
          // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
          // recommends using a cryptographically random +ve 64-bit value
          // but right now this should be acceptable and within the right range
          SDPUtils.generateSessionId = function () {
            return Math.random().toString().substr(2, 21);
          };

          // Write boiler plate for start of SDP
          // sessId argument is optional - if not supplied it will
          // be generated randomly
          // sessVersion is optional and defaults to 2
          // sessUser is optional and defaults to 'thisisadapterortc'
          SDPUtils.writeSessionBoilerplate = function (
            sessId,
            sessVer,
            sessUser
          ) {
            var sessionId = void 0;
            var version = sessVer !== undefined ? sessVer : 2;
            if (sessId) {
              sessionId = sessId;
            } else {
              sessionId = SDPUtils.generateSessionId();
            }
            var user = sessUser || "thisisadapterortc";
            // FIXME: sess-id should be an NTP timestamp.
            return (
              "v=0\r\n" +
              "o=" +
              user +
              " " +
              sessionId +
              " " +
              version +
              " IN IP4 127.0.0.1\r\n" +
              "s=-\r\n" +
              "t=0 0\r\n"
            );
          };

          // Gets the direction from the mediaSection or the sessionpart.
          SDPUtils.getDirection = function (mediaSection, sessionpart) {
            // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
            var lines = SDPUtils.splitLines(mediaSection);
            for (var i = 0; i < lines.length; i++) {
              switch (lines[i]) {
                case "a=sendrecv":
                case "a=sendonly":
                case "a=recvonly":
                case "a=inactive":
                  return lines[i].substr(2);
                default:
                // FIXME: What should happen here?
              }
            }
            if (sessionpart) {
              return SDPUtils.getDirection(sessionpart);
            }
            return "sendrecv";
          };

          SDPUtils.getKind = function (mediaSection) {
            var lines = SDPUtils.splitLines(mediaSection);
            var mline = lines[0].split(" ");
            return mline[0].substr(2);
          };

          SDPUtils.isRejected = function (mediaSection) {
            return mediaSection.split(" ", 2)[1] === "0";
          };

          SDPUtils.parseMLine = function (mediaSection) {
            var lines = SDPUtils.splitLines(mediaSection);
            var parts = lines[0].substr(2).split(" ");
            return {
              kind: parts[0],
              port: parseInt(parts[1], 10),
              protocol: parts[2],
              fmt: parts.slice(3).join(" "),
            };
          };

          SDPUtils.parseOLine = function (mediaSection) {
            var line = SDPUtils.matchPrefix(mediaSection, "o=")[0];
            var parts = line.substr(2).split(" ");
            return {
              username: parts[0],
              sessionId: parts[1],
              sessionVersion: parseInt(parts[2], 10),
              netType: parts[3],
              addressType: parts[4],
              address: parts[5],
            };
          };

          // a very naive interpretation of a valid SDP.
          SDPUtils.isValidSDP = function (blob) {
            if (typeof blob !== "string" || blob.length === 0) {
              return false;
            }
            var lines = SDPUtils.splitLines(blob);
            for (var i = 0; i < lines.length; i++) {
              if (lines[i].length < 2 || lines[i].charAt(1) !== "=") {
                return false;
              }
              // TODO: check the modifier a bit more.
            }
            return true;
          };

          // Expose public methods.
          if (
            (typeof module === "undefined" ? "undefined" : _typeof(module)) ===
            "object"
          ) {
            module.exports = SDPUtils;
          }
        },
        {},
      ],
    },
    {},
    [1]
  )(1);
});
